Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v6.24] Cling: prevent double release of Transactions #153

21 changes: 11 additions & 10 deletions core/clingutils/src/TClingUtils.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/PushTransactionRAII.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Utils/AST.h"

#include "llvm/Support/Path.h"
Expand Down Expand Up @@ -817,7 +818,7 @@ bool ROOT::TMetaUtils::RequireCompleteType(const cling::Interpreter &interp, cla
clang::Sema& S = interp.getCI()->getSema();
// Here we might not have an active transaction to handle
// the caused instantiation decl.
cling::Interpreter::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&interp));
cling::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&interp));
return S.RequireCompleteType(Loc, Type, clang::diag::err_incomplete_type);
}

Expand Down Expand Up @@ -1050,7 +1051,7 @@ bool ROOT::TMetaUtils::CheckDefaultConstructor(const clang::CXXRecordDecl* cl, c
clang::CXXRecordDecl* ncCl = const_cast<clang::CXXRecordDecl*>(cl);

// We may induce template instantiation
cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
cling::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));

if (auto* Ctor = interpreter.getCI()->getSema().LookupDefaultConstructor(ncCl)) {
if (Ctor->getAccess() == clang::AS_public && !Ctor->isDeleted()) {
Expand Down Expand Up @@ -1083,7 +1084,7 @@ ROOT::TMetaUtils::EIOCtorCategory ROOT::TMetaUtils::CheckIOConstructor(const cla
return EIOCtorCategory::kAbsent;

// FIXME: We should not iterate here. That costs memory!
cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
cling::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
for (auto iter = cl->ctor_begin(), end = cl->ctor_end(); iter != end; ++iter)
{
if ((iter->getAccess() != clang::AS_public) || (iter->getNumParams() != 1))
Expand Down Expand Up @@ -1234,7 +1235,7 @@ bool ROOT::TMetaUtils::NeedDestructor(const clang::CXXRecordDecl *cl,

if (cl->hasUserDeclaredDestructor()) {

cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interp));
cling::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interp));
clang::CXXDestructorDecl *dest = cl->getDestructor();
if (dest) {
return (dest->getAccess() == clang::AS_public);
Expand Down Expand Up @@ -3064,7 +3065,7 @@ clang::QualType ROOT::TMetaUtils::AddDefaultParameters(clang::QualType instanceT
clang::TemplateTypeParmDecl *TTP = llvm::dyn_cast<clang::TemplateTypeParmDecl>(*Param);
{
// We may induce template instantiation
cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
cling::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
clang::sema::HackForDefaultTemplateArg raii;
bool HasDefaultArgs;
clang::TemplateArgumentLoc ArgType = S.SubstDefaultTemplateArgumentIfAvailable(
Expand Down Expand Up @@ -3506,7 +3507,7 @@ void ROOT::TMetaUtils::GetFullyQualifiedTypeName(std::string &typenamestr,
// We need this because GetFullyQualifiedTypeName is triggering deserialization
// This calling the same name function GetFullyQualifiedTypeName, but this should stay here because
// callee doesn't have an interpreter pointer
cling::Interpreter::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&interpreter));
cling::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&interpreter));

GetFullyQualifiedTypeName(typenamestr,
qtype,
Expand Down Expand Up @@ -3663,7 +3664,7 @@ static bool areEqualTypes(const clang::TemplateArgument& tArg,
TemplateArgument newArg = tArg;
{
clang::Sema& S = interp.getCI()->getSema();
cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interp));
cling::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interp));
clang::sema::HackForDefaultTemplateArg raii; // Hic sunt leones
bool HasDefaultArgs;
TemplateArgumentLoc defTArgLoc = S.SubstDefaultTemplateArgumentIfAvailable(Template,
Expand Down Expand Up @@ -4015,7 +4016,7 @@ clang::QualType ROOT::TMetaUtils::GetNormalizedType(const clang::QualType &type,
clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();

// Modules can trigger deserialization.
cling::Interpreter::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&interpreter));
cling::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&interpreter));
clang::QualType normalizedType = cling::utils::Transform::GetPartiallyDesugaredType(ctxt, type, normCtxt.GetConfig(), true /* fully qualify */);

// Readd missing default template parameters
Expand Down Expand Up @@ -4057,7 +4058,7 @@ void ROOT::TMetaUtils::GetNormalizedName(std::string &norm_name, const clang::Qu
std::string normalizedNameStep1;

// getAsStringInternal can trigger deserialization
cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
cling::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
normalizedType.getAsStringInternal(normalizedNameStep1,policy);

// Still remove the std:: and default template argument for STL container and
Expand Down
3 changes: 2 additions & 1 deletion core/dictgen/src/DictSelectionReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "clang/AST/AST.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/PushTransactionRAII.h"

#include "ClassSelectionRule.h"
#include "SelectionRules.h"
Expand All @@ -27,7 +28,7 @@ DictSelectionReader::DictSelectionReader(cling::Interpreter &interp, SelectionRu

{
// We push a new transaction because we could deserialize decls here
cling::Interpreter::PushTransactionRAII RAII(&interp);
cling::PushTransactionRAII RAII(&interp);
// Inspect the AST
TraverseDecl(translUnitDecl);
}
Expand Down
7 changes: 4 additions & 3 deletions core/dictgen/src/rootcling_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/PushTransactionRAII.h"
#include "cling/Interpreter/Value.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/Basic/Diagnostic.h"
Expand Down Expand Up @@ -3055,7 +3056,7 @@ std::list<std::string> RecordDecl2Headers(const clang::CXXRecordDecl &rcd,
std::list<std::string> headers;

// We push a new transaction because we could deserialize decls here
cling::Interpreter::PushTransactionRAII RAII(&interp);
cling::PushTransactionRAII RAII(&interp);

// Avoid infinite recursion
if (!visitedDecls.insert(rcd.getCanonicalDecl()).second)
Expand Down Expand Up @@ -4341,7 +4342,7 @@ int RootClingMain(int argc,
}
DepMod = GetModuleNameFromRdictName(DepMod);
// We might deserialize.
cling::Interpreter::PushTransactionRAII RAII(&interp);
cling::PushTransactionRAII RAII(&interp);
if (!interp.loadModule(DepMod, /*complain*/false)) {
ROOT::TMetaUtils::Error(0, "Module '%s' failed to load.\n",
DepMod.data());
Expand Down Expand Up @@ -5031,7 +5032,7 @@ int RootClingMain(int argc,
// appropriate deconstructors in the interpreter. This writes out the C++
// module file that we currently generate.
{
cling::Interpreter::PushTransactionRAII RAII(&interp);
cling::PushTransactionRAII RAII(&interp);
CI->getSema().getASTConsumer().HandleTranslationUnit(CI->getSema().getASTContext());
}

Expand Down
22 changes: 11 additions & 11 deletions core/metacling/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp
::Info("TCling::__LoadModule", "Preloading module %s. \n",
ModuleName.c_str());

cling::Interpreter::PushTransactionRAII deserRAII(&interp);
cling::PushTransactionRAII deserRAII(&interp);
return interp.loadModule(ModuleName, /*Complain=*/true);
}

Expand Down Expand Up @@ -1115,7 +1115,7 @@ static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
RecreateIndex = true;
}
if (RecreateIndex) {
cling::Interpreter::PushTransactionRAII deserRAII(&interp);
cling::PushTransactionRAII deserRAII(&interp);
clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;

struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
Expand Down Expand Up @@ -1844,7 +1844,7 @@ void TCling::LoadPCM(std::string pcmFileNameFullPath)
std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
TMemFile pcmMemFile(RDictFileOpts.c_str(), range);

cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
cling::PushTransactionRAII deserRAII(GetInterpreterImpl());
LoadPCMImpl(pcmMemFile);
fPendingRdicts.erase(pendingRdict);

Expand Down Expand Up @@ -2748,7 +2748,7 @@ void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
{
// Force possible deserializations first. We need to have no pending
// Transaction when passing control flow to the inspector below (ROOT-7779).
cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
cling::PushTransactionRAII deserRAII(GetInterpreterImpl());

astContext.getASTRecordLayout(recordDecl);

Expand Down Expand Up @@ -3746,7 +3746,7 @@ Int_t TCling::DeleteVariable(const char* name)
unscopedName += posScope + 2;
}
// Could trigger deserialization of decls.
cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
cling::PushTransactionRAII RAII(GetInterpreterImpl());
clang::NamedDecl* nVarDecl
= cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
if (!nVarDecl) {
Expand Down Expand Up @@ -4292,7 +4292,7 @@ void TCling::LoadEnums(TListOfEnums& enumList) const
}
// Iterate on the decl of the class and get the enums.
if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
cling::PushTransactionRAII deserRAII(GetInterpreterImpl());
// Collect all contexts of the namespace.
llvm::SmallVector< DeclContext *, 4> allDeclContexts;
const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
Expand Down Expand Up @@ -4341,7 +4341,7 @@ void TCling::LoadFunctionTemplates(TClass* cl) const
}
// Iterate on the decl of the class and get the enums.
if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
cling::PushTransactionRAII deserRAII(GetInterpreterImpl());
// Collect all contexts of the namespace.
llvm::SmallVector< DeclContext *, 4> allDeclContexts;
const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
Expand Down Expand Up @@ -4687,7 +4687,7 @@ TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char
Sema::ForExternalRedeclaration);

// Could trigger deserialization of decls.
cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
cling::PushTransactionRAII RAII(GetInterpreterImpl());
cling::utils::Lookup::Named(&SemaR, R);

LookupResult::Filter F = R.makeFilter();
Expand Down Expand Up @@ -4728,7 +4728,7 @@ TInterpreter::DeclId_t TCling::GetEnum(TClass *cl, const char *name) const
if (dc) {
// If it is a data member enum.
// Could trigger deserialization of decls.
cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
cling::PushTransactionRAII RAII(GetInterpreterImpl());
possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
} else {
Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
Expand All @@ -4737,7 +4737,7 @@ TInterpreter::DeclId_t TCling::GetEnum(TClass *cl, const char *name) const
} else {
// If it is a global enum.
// Could trigger deserialization of decls.
cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
cling::PushTransactionRAII RAII(GetInterpreterImpl());
possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
}
if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
Expand Down Expand Up @@ -6816,7 +6816,7 @@ void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
continue;
}
// Could trigger deserialization of decls.
cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
cling::PushTransactionRAII RAII(GetInterpreterImpl());
// Unlock the TClass for updates
((TCling*)gCling)->GetModTClasses().erase(*I);

Expand Down
10 changes: 5 additions & 5 deletions core/metacling/src/TClingBaseClassInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ the Clang C++ compiler, not CINT.

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Transaction.h"

#include "cling/Interpreter/PushTransactionRAII.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
Expand Down Expand Up @@ -78,7 +78,7 @@ TClingBaseClassInfo::TClingBaseClassInfo(cling::Interpreter* interp,
fDecl = CRD;
{
// In particular if the base are templated, this might deserialize.
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);
fIter = CRD->bases_begin();
}
}
Expand Down Expand Up @@ -111,7 +111,7 @@ TClingBaseClassInfo::TClingBaseClassInfo(cling::Interpreter* interp,
clang::CXXBasePaths Paths;

// CXXRecordDecl::isDerivedFrom can trigger deserialization.
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);

if (!CRD->isDerivedFrom(BaseCRD, Paths)) {
//Not valid fBaseInfo = 0.
Expand Down Expand Up @@ -274,7 +274,7 @@ int TClingBaseClassInfo::InternalNext(int onlyDirect)
// now we process the bases of that base class.

// At least getASTRecordLayout() might deserialize.
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);
fDescend = false;
const clang::RecordType *Ty = fIter->getType()->
getAs<clang::RecordType>();
Expand Down Expand Up @@ -389,7 +389,7 @@ static clang::CharUnits computeOffsetHint(clang::ASTContext &Context,
continue;

// Accumulate the base class offsets.
cling::Interpreter::PushTransactionRAII RAII(interp);
cling::PushTransactionRAII RAII(interp);
const clang::ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
}
Expand Down
3 changes: 2 additions & 1 deletion core/metacling/src/TClingCallFunc.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ C++ interpreter and the Clang C++ compiler, not CINT.
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Interpreter/PushTransactionRAII.h"
#include "cling/Interpreter/Value.h"
#include "cling/Utils/AST.h"

Expand Down Expand Up @@ -809,7 +810,7 @@ int TClingCallFunc::get_wrapper_code(std::string &wrapper_name, std::string &wra
clang::FunctionDecl *FDmod = const_cast<clang::FunctionDecl *>(FD);
clang::Sema &S = fInterp->getSema();
// Could trigger deserialization of decls.
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);
S.InstantiateFunctionDefinition(SourceLocation(), FDmod,
/*Recursive=*/true,
/*DefinitionRequired=*/true);
Expand Down
11 changes: 6 additions & 5 deletions core/metacling/src/TClingClassInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ but the class metadata comes from the Clang C++ compiler, not CINT.

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/PushTransactionRAII.h"
#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
Expand Down Expand Up @@ -148,7 +149,7 @@ long TClingClassInfo::ClassProperty() const
const RecordDecl *RD = llvm::dyn_cast<RecordDecl>(GetDecl());

// isAbstract and other calls can trigger deserialization
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);

if (!RD) {
// We are an enum or namespace.
Expand Down Expand Up @@ -646,7 +647,7 @@ std::vector<std::string> TClingClassInfo::GetUsingNamespaces()

R__LOCKGUARD(gInterpreterMutex);

cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);
const auto DC = dyn_cast<DeclContext>(fDecl);
if (!DC)
return res;
Expand Down Expand Up @@ -929,7 +930,7 @@ int TClingClassInfo::InternalNext()
fDeclFileName.clear(); // invalidate decl file name.
fNameCache.clear(); // invalidate the cache.

cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);
if (fFirstTime) {
// GetDecl() must be a DeclContext in order to iterate.
const clang::DeclContext *DC = cast<DeclContext>(GetDecl());
Expand Down Expand Up @@ -1256,7 +1257,7 @@ long TClingClassInfo::Property() const
property |= kIsCPPCompiled;

// Modules can deserialize while querying the various decls for information.
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);

const clang::DeclContext *ctxt = GetDecl()->getDeclContext();
clang::NamespaceDecl *std_ns =fInterp->getSema().getStdNamespace();
Expand Down Expand Up @@ -1339,7 +1340,7 @@ int TClingClassInfo::Size() const
return 0;
}
ASTContext &Context = GetDecl()->getASTContext();
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
int64_t size = Layout.getSize().getQuantity();
int clang_size = static_cast<int>(size);
Expand Down
5 changes: 3 additions & 2 deletions core/metacling/src/TClingDataMemberInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ from the Clang C++ compiler, not CINT.
#include "TVirtualMutex.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/PushTransactionRAII.h"

#include "clang/AST/Attr.h"
#include "clang/AST/ASTContext.h"
Expand Down Expand Up @@ -335,7 +336,7 @@ long TClingDataMemberInfo::Offset()
// Could trigger deserialization of decls, in particular in case
// of constexpr, like:
// static constexpr Long64_t something = std::numeric_limits<Long64_t>::max();
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);

if (long addr = reinterpret_cast<long>(fInterp->getAddressOfGlobal(GlobalDecl(VD))))
return addr;
Expand Down Expand Up @@ -479,7 +480,7 @@ long TClingDataMemberInfo::Property() const
const clang::TagType *tt = qt->getAs<clang::TagType>();
if (tt) {
// tt->getDecl() might deserialize.
cling::Interpreter::PushTransactionRAII RAII(fInterp);
cling::PushTransactionRAII RAII(fInterp);
const clang::TagDecl *td = tt->getDecl();
if (td->isClass()) {
property |= kIsClass;
Expand Down
Loading