aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/GRExprEngine.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-11-16 07:52:17 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-11-16 07:52:17 +0000
commit9dc84c9455df2a77195147d0210c915dc1775a88 (patch)
tree17f323502c631bd4a851a4ad8f5470d170c3f42a /lib/Checker/GRExprEngine.cpp
parenta437ad3ec5b407ede394d74e6f9f463fa3657dbe (diff)
Handle member initializer in C++ ctor.
- Add a new Kind of ProgramPoint: PostInitializer. - Still use GRStmtNodeBuilder. But special handling PostInitializer in GRStmtNodeBuilder::GenerateAutoTransition(). - Someday we should clean up the interface of GRStmtNodeBuilder. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119335 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/GRExprEngine.cpp')
-rw-r--r--lib/Checker/GRExprEngine.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp
index 017a6959cc..acb67d63dc 100644
--- a/lib/Checker/GRExprEngine.cpp
+++ b/lib/Checker/GRExprEngine.cpp
@@ -327,7 +327,7 @@ GRExprEngine::GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf)
SymMgr(StateMgr.getSymbolManager()),
ValMgr(StateMgr.getValueManager()),
SVator(ValMgr.getSValuator()),
- CurrentStmt(NULL),
+ EntryNode(NULL), CurrentStmt(NULL),
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
RaiseSel(GetNullarySelector("raise", getContext())),
BR(mgr, *this), TF(tf) {
@@ -679,8 +679,41 @@ void GRExprEngine::ProcessStmt(const CFGStmt S, GRStmtNodeBuilder& builder) {
Builder = NULL;
}
-void GRExprEngine::ProcessInitializer(const CFGInitializer I,
+void GRExprEngine::ProcessInitializer(const CFGInitializer Init,
GRStmtNodeBuilder &builder) {
+ // We don't set EntryNode and CurrentStmt. And we don't clean up state.
+ const CXXBaseOrMemberInitializer *BMI = Init.getInitializer();
+
+ ExplodedNode *Pred = builder.getBasePredecessor();
+ const LocationContext *LC = Pred->getLocationContext();
+
+ if (BMI->isMemberInitializer()) {
+ ExplodedNodeSet Dst;
+
+ // Evaluate the initializer.
+ 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->getMember();
+ 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 InitVal = state->getSVal(BMI->getInit());
+ state = state->bindLoc(FieldLoc, InitVal);
+
+ // Use a custom node building process.
+ PostInitializer PP(BMI, LC);
+ // Builder automatically add the generated node to the deferred set,
+ // which are processed in the builder's dtor.
+ builder.generateNode(PP, state, Pred);
+ }
+ }
}
void GRExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
@@ -1566,7 +1599,8 @@ void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) {
// Bind the constructed object value to CXXConstructExpr.
if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
- const CXXThisRegion *ThisR = getCXXThisRegion(CCE->getConstructor(),LocCtx);
+ const CXXThisRegion *ThisR =
+ getCXXThisRegion(CCE->getConstructor()->getParent(), LocCtx);
// We might not have 'this' region in the binding if we didn't inline
// the ctor call.
SVal ThisV = state->getSVal(ThisR);