From e248dca3003f66e06bb739f77ff65033da29e02a Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Tue, 23 Mar 2010 09:13:17 +0000 Subject: [PATCH] Bind the constructed object value to CXXConstructExpr. llvm-svn: 99271 --- .../Checker/PathSensitive/GRExprEngine.h | 4 +++ clang/lib/Checker/GRExprEngine.cpp | 26 ++++++++++++++++--- clang/lib/Checker/RegionStore.cpp | 5 ++-- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Checker/PathSensitive/GRExprEngine.h b/clang/include/clang/Checker/PathSensitive/GRExprEngine.h index d95f3c245403..2b5feddf5855 100644 --- a/clang/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -358,6 +358,10 @@ public: void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst); + /// Synthesize CXXThisRegion. + const CXXThisRegion *getCXXThisRegion(const CXXConstructExpr *E, + const StackFrameContext *SFC); + /// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) /// with those assumptions. diff --git a/clang/lib/Checker/GRExprEngine.cpp b/clang/lib/Checker/GRExprEngine.cpp index 8ed57e70934c..b5521859d178 100644 --- a/clang/lib/Checker/GRExprEngine.cpp +++ b/clang/lib/Checker/GRExprEngine.cpp @@ -1333,6 +1333,20 @@ void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) { state = state->set(0); } + // Bind the constructed object value to CXXConstructExpr. + if (const CXXConstructExpr *CCE = dyn_cast(CE)) { + const CXXThisRegion *ThisR = getCXXThisRegion(CCE, LocCtx); + // We might not have 'this' region in the binding if we didn't inline + // the ctor call. + SVal ThisV = state->getSVal(ThisR); + loc::MemRegionVal *V = dyn_cast(&ThisV); + if (V) { + SVal ObjVal = state->getSVal(V->getRegion()); + assert(isa(ObjVal)); + state = state->BindExpr(CCE, ObjVal); + } + } + B.GenerateNode(state); } @@ -3198,10 +3212,7 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest, Pred->getLocationContext(), E, Builder->getBlock(), Builder->getIndex()); - Type *T = CD->getParent()->getTypeForDecl(); - QualType PT = getContext().getPointerType(QualType(T,0)); - const CXXThisRegion *ThisR = ValMgr.getRegionManager().getCXXThisRegion(PT, - SFC); + const CXXThisRegion *ThisR = getCXXThisRegion(E, SFC); CallEnter Loc(E, CD, Pred->getLocationContext()); for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(), @@ -3214,6 +3225,13 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest, Dst.Add(N); } } + +const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXConstructExpr *E, + const StackFrameContext *SFC) { + Type *T = E->getConstructor()->getParent()->getTypeForDecl(); + QualType PT = getContext().getPointerType(QualType(T,0)); + return ValMgr.getRegionManager().getCXXThisRegion(PT, SFC); +} //===----------------------------------------------------------------------===// // Checker registration/lookup. //===----------------------------------------------------------------------===// diff --git a/clang/lib/Checker/RegionStore.cpp b/clang/lib/Checker/RegionStore.cpp index c2b702acad9a..19cf6d51e088 100644 --- a/clang/lib/Checker/RegionStore.cpp +++ b/clang/lib/Checker/RegionStore.cpp @@ -1044,7 +1044,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) { } #endif - if (RTy->isStructureType()) + if (RTy->isStructureType() || RTy->isClassType()) return RetrieveStruct(store, R); // FIXME: Handle unions. @@ -1337,8 +1337,7 @@ SVal RegionStoreManager::RetrieveLazySymbol(const TypedRegion *R) { SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) { QualType T = R->getValueType(getContext()); - assert(T->isStructureType()); - assert(T->getAsStructureType()->getDecl()->isDefinition()); + assert(T->isStructureType() || T->isClassType()); return ValMgr.makeLazyCompoundVal(store, R); }