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/ExprEngineC.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/ExprEngineC.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineC.cpp | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index c2590d5ef2..183a7f5362 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -454,30 +454,37 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, if (const Expr *InitEx = VD->getInit()) { SVal InitVal = state->getSVal(InitEx, Pred->getLocationContext()); - - // We bound the temp obj region to the CXXConstructExpr. Now recover - // the lazy compound value when the variable is not a reference. - if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() && - !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){ - InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion()); - assert(isa<nonloc::LazyCompoundVal>(InitVal)); - } - - // Recover some path-sensitivity if a scalar value evaluated to - // UnknownVal. - if (InitVal.isUnknown()) { - QualType Ty = InitEx->getType(); - if (InitEx->isGLValue()) { - Ty = getContext().getPointerType(Ty); - } - - InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, LC, Ty, - currentBuilderContext->getCurrentBlockCount()); + + if (InitVal == state->getLValue(VD, LC)) { + // We constructed the object directly in the variable. + // No need to bind anything. + B.generateNode(DS, N, state); + } else { + // We bound the temp obj region to the CXXConstructExpr. Now recover + // the lazy compound value when the variable is not a reference. + // FIXME: This is probably not correct for most constructors! + if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() && + !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){ + InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion()); + assert(isa<nonloc::LazyCompoundVal>(InitVal)); + } + + // Recover some path-sensitivity if a scalar value evaluated to + // UnknownVal. + if (InitVal.isUnknown()) { + QualType Ty = InitEx->getType(); + if (InitEx->isGLValue()) { + Ty = getContext().getPointerType(Ty); + } + + InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, LC, Ty, + currentBuilderContext->getCurrentBlockCount()); + } + B.takeNodes(N); + ExplodedNodeSet Dst2; + evalBind(Dst2, DS, N, state->getLValue(VD, LC), InitVal, true); + B.addNodes(Dst2); } - B.takeNodes(N); - ExplodedNodeSet Dst2; - evalBind(Dst2, DS, N, state->getLValue(VD, LC), InitVal, true); - B.addNodes(Dst2); } else { B.generateNode(DS, N,state->bindDeclWithNoInit(state->getRegion(VD, LC))); |