This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rL324800: [analyzer] NFC: Use CFG construction contexts instead of homemade lookahead. (authored by dergachev, committed by ). Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D42721?vs=133732&id=133735#toc Repository: rL LLVM https://reviews.llvm.org/D42721 Files: cfe/trunk/include/clang/Analysis/CFG.h cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -114,12 +114,14 @@ const LocationContext *LCtx = Pred->getLocationContext(); ProgramStateRef State = Pred->getState(); - // See if we're constructing an existing region by looking at the next - // element in the CFG. - - if (auto Elem = findElementDirectlyInitializedByCurrentConstructor()) { - if (Optional<CFGStmt> StmtElem = Elem->getAs<CFGStmt>()) { - if (const CXXNewExpr *CNE = dyn_cast<CXXNewExpr>(StmtElem->getStmt())) { + // See if we're constructing an existing region by looking at the + // current construction context. + const NodeBuilderContext &CurrBldrCtx = getBuilderContext(); + const CFGBlock *B = CurrBldrCtx.getBlock(); + const CFGElement &E = (*B)[currStmtIdx]; + if (auto CC = E.getAs<CFGConstructor>()) { + if (const Stmt *TriggerStmt = CC->getTriggerStmt()) { + if (const CXXNewExpr *CNE = dyn_cast<CXXNewExpr>(TriggerStmt)) { if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) { // TODO: Detect when the allocator returns a null pointer. // Constructor shall not be called in this case. @@ -135,7 +137,7 @@ return MR; } } - } else if (auto *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) { + } else if (auto *DS = dyn_cast<DeclStmt>(TriggerStmt)) { if (const auto *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) { if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) { SVal LValue = State->getLValue(Var, LCtx); @@ -145,11 +147,9 @@ return LValue.getAsRegion(); } } - } else { - llvm_unreachable("Unexpected directly initialized element!"); } - } else if (Optional<CFGInitializer> InitElem = Elem->getAs<CFGInitializer>()) { - const CXXCtorInitializer *Init = InitElem->getInitializer(); + // TODO: Consider other directly initialized elements. + } else if (const CXXCtorInitializer *Init = CC->getTriggerInit()) { assert(Init->isAnyMemberInitializer()); const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); Loc ThisPtr = @@ -183,53 +183,6 @@ return MRMgr.getCXXTempObjectRegion(CE, LCtx); } -/// Returns true if the initializer for \Elem can be a direct -/// constructor. -static bool canHaveDirectConstructor(CFGElement Elem){ - // DeclStmts and CXXCtorInitializers for fields can be directly constructed. - - if (Optional<CFGStmt> StmtElem = Elem.getAs<CFGStmt>()) { - if (isa<DeclStmt>(StmtElem->getStmt())) { - return true; - } - if (isa<CXXNewExpr>(StmtElem->getStmt())) { - return true; - } - } - - if (Elem.getKind() == CFGElement::Initializer) { - return true; - } - - return false; -} - -Optional<CFGElement> -ExprEngine::findElementDirectlyInitializedByCurrentConstructor() { - const NodeBuilderContext &CurrBldrCtx = getBuilderContext(); - // See if we're constructing an existing region by looking at the next - // element in the CFG. - const CFGBlock *B = CurrBldrCtx.getBlock(); - assert(isa<CXXConstructExpr>(((*B)[currStmtIdx]).castAs<CFGStmt>().getStmt())); - unsigned int NextStmtIdx = currStmtIdx + 1; - if (NextStmtIdx >= B->size()) - return None; - - CFGElement Next = (*B)[NextStmtIdx]; - - // Is this a destructor? If so, we might be in the middle of an assignment - // to a local or member: look ahead one more element to see what we find. - while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) { - ++NextStmtIdx; - Next = (*B)[NextStmtIdx]; - } - - if (canHaveDirectConstructor(Next)) - return Next; - - return None; -} - const CXXConstructExpr * ExprEngine::findDirectConstructorForCurrentCFGElement() { // Go backward in the CFG to see if the previous element (ignoring @@ -241,7 +194,6 @@ return nullptr; const CFGBlock *B = getBuilderContext().getBlock(); - assert(canHaveDirectConstructor((*B)[currStmtIdx])); unsigned int PreviousStmtIdx = currStmtIdx - 1; CFGElement Previous = (*B)[PreviousStmtIdx]; Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h =================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -665,13 +665,6 @@ /// constructing into an existing region. const CXXConstructExpr *findDirectConstructorForCurrentCFGElement(); - /// For a CXXConstructExpr, walk forward in the current CFG block to find the - /// CFGElement for the DeclStmt or CXXInitCtorInitializer or CXXNewExpr which - /// is directly constructed by this constructor. Returns None if the current - /// constructor expression did not directly construct into an existing - /// region. - Optional<CFGElement> findElementDirectlyInitializedByCurrentConstructor(); - /// For a given constructor, look forward in the current CFG block to /// determine the region into which an object will be constructed by \p CE. /// When the lookahead fails, a temporary region is returned, and the Index: cfe/trunk/include/clang/Analysis/CFG.h =================================================================== --- cfe/trunk/include/clang/Analysis/CFG.h +++ cfe/trunk/include/clang/Analysis/CFG.h @@ -162,6 +162,8 @@ bool isNull() const { return Trigger.isNull(); } + TriggerTy getTrigger() const { return Trigger; } + const Stmt *getTriggerStmt() const { return Trigger.dyn_cast<Stmt *>(); } @@ -192,6 +194,14 @@ return static_cast<ConstructionContext *>(Data2.getPointer()); } + QualType getType() const { + return cast<CXXConstructExpr>(getStmt())->getType(); + } + + ConstructionContext::TriggerTy getTrigger() const { + return getConstructionContext()->getTrigger(); + } + const Stmt *getTriggerStmt() const { return getConstructionContext()->getTriggerStmt(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits