diff --git a/clang/include/clang/Analysis/PathSensitive/Store.h b/clang/include/clang/Analysis/PathSensitive/Store.h index 9d41de7bd5b6..f6ad582cb801 100644 --- a/clang/include/clang/Analysis/PathSensitive/Store.h +++ b/clang/include/clang/Analysis/PathSensitive/Store.h @@ -37,13 +37,20 @@ class SubRegionMap; class StoreManager { protected: ValueManager &ValMgr; + GRStateManager &StateMgr; /// MRMgr - Manages region objects associated with this StoreManager. MemRegionManager &MRMgr; - StoreManager(ValueManager &valMgr) - : ValMgr(valMgr), MRMgr(ValMgr.getRegionManager()) {} + StoreManager(GRStateManager &stateMgr); +protected: + virtual const GRState* AddRegionView(const GRState* St, + const MemRegion* View, + const MemRegion* Base) { + return St; + } + public: virtual ~StoreManager() {} @@ -125,8 +132,8 @@ public: /// 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. - virtual CastResult CastRegion(const GRState* state, const MemRegion* R, - QualType CastToTy) = 0; + CastResult CastRegion(const GRState* state, const MemRegion* R, + QualType CastToTy); /// EvalBinOp - Perform pointer arithmetic. virtual SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) { diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp index cf8d3176c45b..616c4b51350a 100644 --- a/clang/lib/Analysis/BasicStore.cpp +++ b/clang/lib/Analysis/BasicStore.cpp @@ -35,14 +35,12 @@ public: class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager { BindingsTy::Factory VBFactory; - GRStateManager& StateMgr; const MemRegion* SelfRegion; public: BasicStoreManager(GRStateManager& mgr) - : StoreManager(mgr.getValueManager()), + : StoreManager(mgr), VBFactory(mgr.getAllocator()), - StateMgr(mgr), SelfRegion(0) {} ~BasicStoreManager() {} @@ -87,12 +85,6 @@ public: /// conversions between arrays and pointers. SVal ArrayToPointer(Loc Array) { return Array; } - /// 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. - CastResult CastRegion(const GRState* state, const MemRegion* R, - QualType CastToTy); - /// getSelfRegion - Returns the region for the 'self' (Objective-C) or /// 'this' object (C++). When used when analyzing a normal function this /// method returns NULL. @@ -168,27 +160,7 @@ SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D, return UnknownVal(); } - -/// 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. -StoreManager::CastResult -BasicStoreManager::CastRegion(const GRState* state, const MemRegion* R, - QualType CastToTy) { - // Return the same region if the region types are compatible. - if (const TypedRegion* TR = dyn_cast(R)) { - ASTContext& Ctx = StateMgr.getContext(); - QualType Ta = Ctx.getCanonicalType(TR->getLValueType(Ctx)); - QualType Tb = Ctx.getCanonicalType(CastToTy); - - if (Ta == Tb) - return CastResult(state, R); - } - - return CastResult(state, MRMgr.getTypedViewRegion(CastToTy, R)); -} - SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base, const FieldDecl* D) { diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 40f7c481317a..7a78036ec06f 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -142,16 +142,15 @@ class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager { RegionBindingsTy::Factory RBFactory; RegionViews::Factory RVFactory; - GRStateManager& StateMgr; const MemRegion* SelfRegion; const ImplicitParamDecl *SelfDecl; public: RegionStoreManager(GRStateManager& mgr) - : StoreManager(mgr.getValueManager()), + : StoreManager(mgr), RBFactory(mgr.getAllocator()), RVFactory(mgr.getAllocator()), - StateMgr(mgr), SelfRegion(0), SelfDecl(0) { + SelfRegion(0), SelfDecl(0) { if (const ObjCMethodDecl* MD = dyn_cast(&StateMgr.getCodeDecl())) SelfDecl = MD->getSelfDecl(); @@ -199,12 +198,6 @@ public: /// casts from arrays to pointers. SVal ArrayToPointer(Loc Array); - /// 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. - CastResult CastRegion(const GRState* state, const MemRegion* R, - QualType CastToTy); - SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R); /// The high level logic for this method is this: @@ -579,31 +572,6 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) { return loc::MemRegionVal(ER); } -StoreManager::CastResult -RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R, - QualType CastToTy) { - - // Return the same region if the region types are compatible. - if (const TypedRegion* TR = dyn_cast(R)) { - ASTContext& Ctx = StateMgr.getContext(); - QualType Ta = Ctx.getCanonicalType(TR->getLValueType(Ctx)); - QualType Tb = Ctx.getCanonicalType(CastToTy); - - if (Ta == Tb) - return CastResult(state, R); - } - - // FIXME: We should handle the case when we are casting *back* to a - // previous type. For example: - // - // void* x = ...; - // char* y = (char*) x; - // void* z = (void*) y; // <-- we should get the same region that is - // bound to 'x' - const MemRegion* ViewR = MRMgr.getTypedViewRegion(CastToTy, R); - return CastResult(AddRegionView(state, ViewR, R), ViewR); -} - SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) { // Assume the base location is MemRegionVal(ElementRegion). if (!isa(L)) diff --git a/clang/lib/Analysis/Store.cpp b/clang/lib/Analysis/Store.cpp new file mode 100644 index 000000000000..edd353d0f21a --- /dev/null +++ b/clang/lib/Analysis/Store.cpp @@ -0,0 +1,47 @@ +//== Store.cpp - Interface for maps from Locations to Values ----*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defined the types Store and StoreManager. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/Store.h" +#include "clang/Analysis/PathSensitive/GRState.h" + +using namespace clang; + +StoreManager::StoreManager(GRStateManager &stateMgr) + : ValMgr(stateMgr.getValueManager()), + StateMgr(stateMgr), + MRMgr(ValMgr.getRegionManager()) {} + +StoreManager::CastResult +StoreManager::CastRegion(const GRState* state, const MemRegion* R, + QualType CastToTy) { + + // Return the same region if the region types are compatible. + if (const TypedRegion* TR = dyn_cast(R)) { + ASTContext& Ctx = StateMgr.getContext(); + QualType Ta = Ctx.getCanonicalType(TR->getLValueType(Ctx)); + QualType Tb = Ctx.getCanonicalType(CastToTy); + + if (Ta == Tb) + return CastResult(state, R); + } + + // FIXME: We should handle the case when we are casting *back* to a + // previous type. For example: + // + // void* x = ...; + // char* y = (char*) x; + // void* z = (void*) y; // <-- we should get the same region that is + // bound to 'x' + const MemRegion* ViewR = MRMgr.getTypedViewRegion(CastToTy, R); + return CastResult(AddRegionView(state, ViewR, R), ViewR); +}