summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2018-02-10 02:55:08 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2018-02-10 02:55:08 +0000
commitafb158c2071b2d3a68f1a945d8662911cf51b711 (patch)
tree467ff1265c75987e3fb6c51b2086a6a42f21c370 /clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
parent9bfdb770cc7f513546468e9a4867fa9fdce6caaf (diff)
downloadbcm5719-llvm-afb158c2071b2d3a68f1a945d8662911cf51b711.tar.gz
bcm5719-llvm-afb158c2071b2d3a68f1a945d8662911cf51b711.zip
[analyzer] NFC: Use CFG construction contexts instead of homemade lookahead.
The analyzer was relying on peeking the next CFG element during analysis whenever it was trying to figure out what object is being constructed by a given constructor. This information is now available in the current CFG element in all cases that were previously supported by the analyzer, so no complicated lookahead is necessary anymore. No functional change intended - the context in the CFG should for now be available if and only if it was previously discoverable via CFG lookahead. Differential Revision: https://reviews.llvm.org/D42721 llvm-svn: 324800
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp70
1 files changed, 11 insertions, 59 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 3b7f0aa9127..6786c89c8f2 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -114,12 +114,14 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE,
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 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE,
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 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE,
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 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE,
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 @@ ExprEngine::findDirectConstructorForCurrentCFGElement() {
return nullptr;
const CFGBlock *B = getBuilderContext().getBlock();
- assert(canHaveDirectConstructor((*B)[currStmtIdx]));
unsigned int PreviousStmtIdx = currStmtIdx - 1;
CFGElement Previous = (*B)[PreviousStmtIdx];
OpenPOWER on IntegriCloud