diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-10 22:08:01 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-10 22:08:01 +0000 |
commit | 48b6247804eacc262cc5508e0fbb74ed819fbb6e (patch) | |
tree | 16956a95560e5e0ba92ca6453f2f620f38f6cdc3 /lib/StaticAnalyzer/Core/ExprEngine.cpp | |
parent | e54cfc7b9990acffd0a8a4ba381717b4bb9f3011 (diff) |
[analyzer] Construct stack variables directly in their VarDecl.
Also contains a number of tweaks to inlining that are necessary
for constructors and destructors. (I have this enabled on a private
branch, but it is very much unstable.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160023 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 5e0a338084..d78234890b 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -375,6 +375,7 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init, const FieldDecl *FD = BMI->getAnyMember(); + // FIXME: This does not work for initializers that call constructors. SVal FieldLoc = state->getLValue(FD, thisVal); SVal InitVal = state->getSVal(BMI->getInit(), Pred->getLocationContext()); state = state->bindLoc(FieldLoc, InitVal); @@ -458,7 +459,27 @@ void ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst) {} -void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, +static const VarDecl *findDirectConstruction(const DeclStmt *DS, + const Expr *Init) { + for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end(); + I != E; ++I) { + const VarDecl *Var = dyn_cast<VarDecl>(*I); + if (!Var) + continue; + if (Var->getInit() != Init) + continue; + // FIXME: We need to decide how copy-elision should work here. + if (!Var->isDirectInit()) + break; + if (Var->getType()->isReferenceType()) + break; + return Var; + } + + return 0; +} + +void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &DstTop) { PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), S->getLocStart(), @@ -724,10 +745,18 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::CXXTemporaryObjectExprClass: case Stmt::CXXConstructExprClass: { const CXXConstructExpr *C = cast<CXXConstructExpr>(S); - // For block-level CXXConstructExpr, we don't have a destination region. - // Let VisitCXXConstructExpr() create one. + const MemRegion *Target = 0; + + const LocationContext *LCtx = Pred->getLocationContext(); + const ParentMap &PM = LCtx->getParentMap(); + if (const DeclStmt *DS = dyn_cast_or_null<DeclStmt>(PM.getParent(C))) + if (const VarDecl *Var = findDirectConstruction(DS, C)) + Target = Pred->getState()->getLValue(Var, LCtx).getAsRegion(); + // If we don't have a destination region, VisitCXXConstructExpr() will + // create one. + Bldr.takeNodes(Pred); - VisitCXXConstructExpr(C, 0, Pred, Dst); + VisitCXXConstructExpr(C, Target, Pred, Dst); Bldr.addNodes(Dst); break; } |