aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2011-01-13 12:30:12 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2011-01-13 12:30:12 +0000
commitd074441e027471a914cbb909a7aad1d43224950f (patch)
tree00b080ed9a0662effebaaa7d09294534403900cf /lib/StaticAnalyzer/Checkers/ExprEngine.cpp
parentbda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7 (diff)
Support inlining base initializers. We still haven't got it completely right,
since the bindings are purged after they are set up. Need to investigate RemoveDeadBindings algorithm. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123374 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprEngine.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
index 1577cbee31..874e7a3064 100644
--- a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
@@ -643,36 +643,52 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
// We don't set EntryNode and currentStmt. And we don't clean up state.
const CXXCtorInitializer *BMI = Init.getInitializer();
- ExplodedNode *Pred = builder.getPredecessor();
- const LocationContext *LC = Pred->getLocationContext();
+ ExplodedNode *pred = builder.getPredecessor();
+
+ const StackFrameContext *stackFrame = cast<StackFrameContext>(pred->getLocationContext());
+ const CXXConstructorDecl *decl = cast<CXXConstructorDecl>(stackFrame->getDecl());
+ const CXXThisRegion *thisReg = getCXXThisRegion(decl, stackFrame);
+
+ SVal thisVal = pred->getState()->getSVal(thisReg);
if (BMI->isAnyMemberInitializer()) {
ExplodedNodeSet Dst;
// Evaluate the initializer.
- Visit(BMI->getInit(), Pred, Dst);
+ Visit(BMI->getInit(), pred, Dst);
for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); I != E; ++I){
ExplodedNode *Pred = *I;
const GRState *state = Pred->getState();
const FieldDecl *FD = BMI->getAnyMember();
- const RecordDecl *RD = FD->getParent();
- const CXXThisRegion *ThisR = getCXXThisRegion(cast<CXXRecordDecl>(RD),
- cast<StackFrameContext>(LC));
- SVal ThisV = state->getSVal(ThisR);
- SVal FieldLoc = state->getLValue(FD, ThisV);
+ SVal FieldLoc = state->getLValue(FD, thisVal);
SVal InitVal = state->getSVal(BMI->getInit());
state = state->bindLoc(FieldLoc, InitVal);
// Use a custom node building process.
- PostInitializer PP(BMI, LC);
+ PostInitializer PP(BMI, stackFrame);
// Builder automatically add the generated node to the deferred set,
// which are processed in the builder's dtor.
builder.generateNode(PP, state, Pred);
}
+ return;
}
+
+ assert(BMI->isBaseInitializer());
+
+ // Get the base class declaration.
+ const CXXConstructExpr *ctorExpr = cast<CXXConstructExpr>(BMI->getInit());
+
+ // Create the base object region.
+ SVal baseVal =
+ getStoreManager().evalDerivedToBase(thisVal, ctorExpr->getType());
+ const MemRegion *baseReg = baseVal.getAsRegion();
+ assert(baseReg);
+ Builder = &builder;
+ ExplodedNodeSet dst;
+ VisitCXXConstructExpr(ctorExpr, baseReg, pred, dst);
}
void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,