diff options
-rw-r--r-- | include/clang/Checker/PathSensitive/GRExprEngine.h | 3 | ||||
-rw-r--r-- | include/clang/Checker/PathSensitive/MemRegion.h | 6 | ||||
-rw-r--r-- | include/clang/Checker/PathSensitive/Store.h | 3 | ||||
-rw-r--r-- | lib/Checker/GRExprEngine.cpp | 34 | ||||
-rw-r--r-- | lib/Checker/RegionStore.cpp | 10 | ||||
-rw-r--r-- | lib/Checker/Store.cpp | 7 |
6 files changed, 49 insertions, 14 deletions
diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h index 161cb28df0..1936d58bb8 100644 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -352,6 +352,9 @@ public: void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred, ExplodedNodeSet &Dst); + void VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred, ExplodedNodeSet &Dst); diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h index 57ea8a3f6d..2ab3b420c3 100644 --- a/include/clang/Checker/PathSensitive/MemRegion.h +++ b/include/clang/Checker/PathSensitive/MemRegion.h @@ -869,11 +869,11 @@ public: /// getElementRegion - Retrieve the memory region associated with the /// associated element type, index, and super region. const ElementRegion *getElementRegion(QualType elementType, SVal Idx, - const MemRegion *superRegion, - ASTContext &Ctx); + const MemRegion *superRegion, + ASTContext &Ctx); const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, - const MemRegion *superRegion) { + const MemRegion *superRegion) { return getElementRegion(ER->getElementType(), ER->getIndex(), superRegion, ER->getContext()); } diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h index 72565f4d74..41d7c2bd71 100644 --- a/include/clang/Checker/PathSensitive/Store.h +++ b/include/clang/Checker/PathSensitive/Store.h @@ -129,11 +129,14 @@ public: CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){} }; + const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T); + /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from /// a MemRegion* to a specific location type. 'R' is the region being /// casted and 'CastToTy' the result type of the cast. const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy); + /// EvalBinOp - Perform pointer arithmetic. virtual SVal EvalBinOp(BinaryOperator::Opcode Op, Loc lhs, NonLoc rhs, QualType resultTy) { diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 405c931e04..b6b4caadd3 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -593,7 +593,6 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) { case Stmt::CXXDependentScopeMemberExprClass: case Stmt::CXXExprWithTemporariesClass: case Stmt::CXXNamedCastExprClass: - case Stmt::CXXNewExprClass: case Stmt::CXXNullPtrLiteralExprClass: case Stmt::CXXPseudoDestructorExprClass: case Stmt::CXXTemporaryObjectExprClass: @@ -719,6 +718,12 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) { break; } + case Stmt::CXXNewExprClass: { + CXXNewExpr *NE = cast<CXXNewExpr>(S); + VisitCXXNewExpr(NE, Pred, Dst); + break; + } + // FIXME: ChooseExpr is really a constant. We need to fix // the CFG do not model them as explicit control-flow. @@ -3365,6 +3370,33 @@ void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, } } +void GRExprEngine::VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred, + ExplodedNodeSet &Dst) { + if (CNE->isArray()) { + // FIXME: allocating an array has not been handled. + return; + } + + unsigned Count = Builder->getCurrentBlockCount(); + DefinedOrUnknownSVal SymVal = getValueManager().getConjuredSymbolVal(NULL,CNE, + CNE->getType(), Count); + const MemRegion *NewReg = cast<loc::MemRegionVal>(SymVal).getRegion(); + + QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); + + const ElementRegion *EleReg = + getStoreManager().GetElementZeroRegion(NewReg, ObjTy); + + const GRState *state = Pred->getState(); + + Store store = state->getStore(); + StoreManager::InvalidatedSymbols IS; + store = getStoreManager().InvalidateRegion(store, EleReg, CNE, Count, &IS); + state = state->makeWithStore(store); + state = state->BindExpr(CNE, loc::MemRegionVal(EleReg)); + MakeNode(Dst, CNE, Pred, state); +} + const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXMethodDecl *D, const StackFrameContext *SFC) { Type *T = D->getParent()->getTypeForDecl(); diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index 5e71bb0b3c..73158f2955 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -346,8 +346,6 @@ public: // Part of public interface to class. Store CopyLazyBindings(nonloc::LazyCompoundVal V, Store store, const TypedRegion *R); - const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T); - //===------------------------------------------------------------------===// // State pruning. //===------------------------------------------------------------------===// @@ -995,14 +993,6 @@ static bool IsReinterpreted(QualType RTy, QualType UsedTy, ASTContext &Ctx) { return true; } -const ElementRegion * -RegionStoreManager::GetElementZeroRegion(const MemRegion *R, QualType T) { - ASTContext &Ctx = getContext(); - SVal idx = ValMgr.makeZeroArrayIndex(); - assert(!T.isNull()); - return MRMgr.getElementRegion(T, idx, R, Ctx); -} - SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) { assert(!isa<UnknownVal>(L) && "location unknown"); assert(!isa<UndefinedVal>(L) && "location undefined"); diff --git a/lib/Checker/Store.cpp b/lib/Checker/Store.cpp index 80b6586b8b..c12065b89a 100644 --- a/lib/Checker/Store.cpp +++ b/lib/Checker/Store.cpp @@ -38,6 +38,13 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { return true; } +const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R, + QualType T) { + SVal idx = ValMgr.makeZeroArrayIndex(); + assert(!T.isNull()); + return MRMgr.getElementRegion(T, idx, R, Ctx); +} + const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy) { ASTContext& Ctx = StateMgr.getContext(); |