summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2014-04-01 16:40:06 +0000
committerJordan Rose <jordan_rose@apple.com>2014-04-01 16:40:06 +0000
commit17f416085916e969a19bda802ad3d2968064a8cd (patch)
tree9474450ad6e45ceb796f44b427dfc8dc2f988aa5 /clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
parenta78de33494dc8d0201021b6e7d5cd854cd5f00af (diff)
downloadbcm5719-llvm-17f416085916e969a19bda802ad3d2968064a8cd.tar.gz
bcm5719-llvm-17f416085916e969a19bda802ad3d2968064a8cd.zip
[analyzer] Extract a helper for finding the target region for a C++ constructor.
No functionality change. Patch by Alex McCarthy! llvm-svn: 205328
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp121
1 files changed, 65 insertions, 56 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 5dd16944e78..52fe156e352 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -102,6 +102,70 @@ static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue,
return LValue;
}
+
+static const MemRegion *getRegionForConstructedObject(
+ const CXXConstructExpr *CE, ExplodedNode *Pred, ExprEngine &Eng,
+ unsigned int CurrStmtIdx) {
+ const LocationContext *LCtx = Pred->getLocationContext();
+ ProgramStateRef State = Pred->getState();
+ const NodeBuilderContext &CurrBldrCtx = Eng.getBuilderContext();
+
+ // See if we're constructing an existing region by looking at the next
+ // element in the CFG.
+ const CFGBlock *B = CurrBldrCtx.getBlock();
+ if (CurrStmtIdx + 1 < B->size()) {
+ CFGElement Next = (*B)[CurrStmtIdx+1];
+
+ // Is this a constructor for a local variable?
+ if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
+ if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
+ if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
+ if (Var->getInit()->IgnoreImplicit() == CE) {
+ SVal LValue = State->getLValue(Var, LCtx);
+ QualType Ty = Var->getType();
+ LValue = makeZeroElementRegion(State, LValue, Ty);
+ return LValue.getAsRegion();
+ }
+ }
+ }
+ }
+
+ // Is this a constructor for a member?
+ if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
+ const CXXCtorInitializer *Init = InitElem->getInitializer();
+ assert(Init->isAnyMemberInitializer());
+
+ const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
+ Loc ThisPtr = Eng.getSValBuilder().getCXXThis(CurCtor,
+ LCtx->getCurrentStackFrame());
+ SVal ThisVal = State->getSVal(ThisPtr);
+
+ const ValueDecl *Field;
+ SVal FieldVal;
+ if (Init->isIndirectMemberInitializer()) {
+ Field = Init->getIndirectMember();
+ FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
+ } else {
+ Field = Init->getMember();
+ FieldVal = State->getLValue(Init->getMember(), ThisVal);
+ }
+
+ QualType Ty = Field->getType();
+ FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
+ return FieldVal.getAsRegion();
+ }
+
+ // FIXME: This will eventually need to handle new-expressions as well.
+ // Don't forget to update the pre-constructor initialization code in
+ // ExprEngine::VisitCXXConstructExpr.
+ }
+
+ // If we couldn't find an existing region to construct into, assume we're
+ // constructing a temporary.
+ MemRegionManager &MRMgr = Eng.getSValBuilder().getRegionManager();
+ return MRMgr.getCXXTempObjectRegion(CE, LCtx);
+}
+
void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
ExplodedNode *Pred,
ExplodedNodeSet &destNodes) {
@@ -116,62 +180,7 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
switch (CE->getConstructionKind()) {
case CXXConstructExpr::CK_Complete: {
- // See if we're constructing an existing region by looking at the next
- // element in the CFG.
- const CFGBlock *B = currBldrCtx->getBlock();
- if (currStmtIdx + 1 < B->size()) {
- CFGElement Next = (*B)[currStmtIdx+1];
-
- // Is this a constructor for a local variable?
- if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
- if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
- if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
- if (Var->getInit()->IgnoreImplicit() == CE) {
- SVal LValue = State->getLValue(Var, LCtx);
- QualType Ty = Var->getType();
- LValue = makeZeroElementRegion(State, LValue, Ty);
- Target = LValue.getAsRegion();
- }
- }
- }
- }
-
- // Is this a constructor for a member?
- if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
- const CXXCtorInitializer *Init = InitElem->getInitializer();
- assert(Init->isAnyMemberInitializer());
-
- const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
- Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
- LCtx->getCurrentStackFrame());
- SVal ThisVal = State->getSVal(ThisPtr);
-
- const ValueDecl *Field;
- SVal FieldVal;
- if (Init->isIndirectMemberInitializer()) {
- Field = Init->getIndirectMember();
- FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
- } else {
- Field = Init->getMember();
- FieldVal = State->getLValue(Init->getMember(), ThisVal);
- }
-
- QualType Ty = Field->getType();
- FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
- Target = FieldVal.getAsRegion();
- }
-
- // FIXME: This will eventually need to handle new-expressions as well.
- // Don't forget to update the pre-constructor initialization code below.
- }
-
- // If we couldn't find an existing region to construct into, assume we're
- // constructing a temporary.
- if (!Target) {
- MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
- Target = MRMgr.getCXXTempObjectRegion(CE, LCtx);
- }
-
+ Target = getRegionForConstructedObject(CE, Pred, *this, currStmtIdx);
break;
}
case CXXConstructExpr::CK_VirtualBase:
OpenPOWER on IntegriCloud