diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRState.h | 77 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/Store.h | 102 | ||||
-rw-r--r-- | lib/Analysis/BasicStore.cpp | 59 | ||||
-rw-r--r-- | lib/Analysis/GRState.cpp | 11 | ||||
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 396 |
5 files changed, 360 insertions, 285 deletions
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 44ec98dfd6..700e9f6ec9 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -64,6 +64,8 @@ template <typename T> struct GRStateTrait { //===----------------------------------------------------------------------===// // GRState- An ImmutableMap type Stmt*/Decl*/Symbols to SVals. //===----------------------------------------------------------------------===// + +class GRStateManager; /// GRState - This class encapsulates the actual data values for /// for a "state" in our symbolic value tracking. It is intended to be @@ -81,7 +83,8 @@ private: void operator=(const GRState& R) const; friend class GRStateManager; - + + GRStateManager *Mgr; Environment Env; Store St; @@ -92,8 +95,10 @@ public: public: /// This ctor is used when creating the first GRState object. - GRState(const Environment& env, Store st, GenericDataMap gdm) - : Env(env), + GRState(GRStateManager *mgr, const Environment& env, Store st, + GenericDataMap gdm) + : Mgr(mgr), + Env(env), St(st), GDM(gdm) {} @@ -101,10 +106,14 @@ public: /// in FoldingSetNode will also get copied. GRState(const GRState& RHS) : llvm::FoldingSetNode(), + Mgr(RHS.Mgr), Env(RHS.Env), St(RHS.St), GDM(RHS.GDM) {} + /// getStateManager - Return the GRStateManager associated with this state. + GRStateManager &getStateManager() const { return *Mgr; } + /// getEnvironment - Return the environment associated with this state. /// The environment is the mapping from expressions to values. const Environment& getEnvironment() const { return Env; } @@ -134,6 +143,10 @@ public: return Env.LookupExpr(E); } + /// makeWithStore - Return a GRState with the same values as the current + /// state with the exception of using the specified Store. + const GRState *makeWithStore(Store store) const; + // Iterators. typedef Environment::seb_iterator seb_iterator; seb_iterator seb_begin() const { return Env.seb_begin(); } @@ -146,6 +159,9 @@ public: // Trait based GDM dispatch. void* const* FindGDM(void* K) const; + template<typename T> + const GRState *add(typename GRStateTrait<T>::key_type K) const; + template <typename T> typename GRStateTrait<T>::data_type get() const { @@ -159,6 +175,21 @@ public: return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key); } + template <typename T> + typename GRStateTrait<T>::context_type get_context() const; + + template<typename T> + const GRState *set(typename GRStateTrait<T>::data_type D) const; + + template<typename T> + const GRState *set(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::value_type E) const; + + template<typename T> + const GRState *set(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::value_type E, + typename GRStateTrait<T>::context_type C) const; + template<typename T> bool contains(typename GRStateTrait<T>::key_type key) const { void* const* d = FindGDM(GRStateTrait<T>::GDMIndex()); @@ -533,9 +564,6 @@ public: const GRState* getPersistentState(GRState& Impl); - // MakeStateWithStore - get a persistent state with the new store. - const GRState* MakeStateWithStore(const GRState* St, Store store); - bool isEqual(const GRState* state, Expr* Ex, const llvm::APSInt& V); bool isEqual(const GRState* state, Expr* Ex, uint64_t); @@ -667,6 +695,39 @@ public: SymbolVisitor& visitor); }; + +//===----------------------------------------------------------------------===// +// Out-of-line template method definitions for GRState. +//===----------------------------------------------------------------------===// + +template<typename T> +const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const { + return Mgr->add<T>(this, K, get_context<T>()); +} + +template <typename T> +typename GRStateTrait<T>::context_type GRState::get_context() const { + return Mgr->get_context<T>(); +} + +template<typename T> +const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const { + return Mgr->set<T>(this, D); +} + +template<typename T> +const GRState *GRState::set(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::value_type E) const { + return Mgr->set<T>(this, K, E, get_context<T>()); +} + +template<typename T> +const GRState *GRState::set(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::value_type E, + typename GRStateTrait<T>::context_type C) const { + return Mgr->set<T>(this, K, E, C); +} + //===----------------------------------------------------------------------===// // GRStateRef - A "fat" reference to GRState that also bundles GRStateManager. //===----------------------------------------------------------------------===// @@ -681,10 +742,6 @@ public: operator const GRState*() const { return St; } GRStateManager& getManager() const { return *Mgr; } - GRStateRef makeWithStore(Store store) { - return GRStateRef(Mgr->MakeStateWithStore(St, store), *Mgr); - } - SVal GetSVal(Expr* Ex) { return Mgr->GetSVal(St, Ex); } diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 8274630f79..0c5df2e98e 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -14,12 +14,12 @@ #ifndef LLVM_CLANG_ANALYSIS_STORE_H #define LLVM_CLANG_ANALYSIS_STORE_H -#include "clang/Analysis/PathSensitive/SVals.h" #include "clang/Analysis/PathSensitive/MemRegion.h" +#include "clang/Analysis/PathSensitive/SVals.h" #include "clang/Analysis/PathSensitive/ValueManager.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallVector.h" #include <iosfwd> @@ -45,10 +45,10 @@ protected: StoreManager(GRStateManager &stateMgr); protected: - virtual const GRState* AddRegionView(const GRState* St, - const MemRegion* View, - const MemRegion* Base) { - return St; + virtual const GRState *AddRegionView(const GRState *state, + const MemRegion *view, + const MemRegion *base) { + return state; } public: @@ -61,7 +61,7 @@ public: /// expected type of the returned value. This is used if the value is /// lazily computed. /// \return The value bound to the location \c loc. - virtual SVal Retrieve(const GRState* state, Loc loc, + virtual SVal Retrieve(const GRState *state, Loc loc, QualType T = QualType()) = 0; /// Return a state with the specified value bound to the given location. @@ -71,7 +71,7 @@ public: /// \return A pointer to a GRState object that contains the same bindings as /// \c state with the addition of having the value specified by \c val bound /// to the location given for \c loc. - virtual const GRState* Bind(const GRState* state, Loc loc, SVal val) = 0; + virtual const GRState *Bind(const GRState *state, Loc loc, SVal val) = 0; virtual Store Remove(Store St, Loc L) = 0; @@ -79,9 +79,9 @@ public: /// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region /// for the compound literal and 'BegInit' and 'EndInit' represent an /// array of initializer values. - virtual const GRState* BindCompoundLiteral(const GRState* St, - const CompoundLiteralExpr* CL, - SVal V) = 0; + virtual const GRState *BindCompoundLiteral(const GRState *state, + const CompoundLiteralExpr* cl, + SVal v) = 0; /// getInitialStore - Returns the initial "empty" store representing the /// value bindings upon entry to an analyzed function. @@ -94,51 +94,52 @@ public: /// getSubRegionMap - Returns an opaque map object that clients can query /// to get the subregions of a given MemRegion object. It is the // caller's responsibility to 'delete' the returned map. - virtual SubRegionMap* getSubRegionMap(const GRState *state) = 0; + virtual SubRegionMap *getSubRegionMap(const GRState *state) = 0; - virtual SVal getLValueVar(const GRState* St, const VarDecl* VD) = 0; + virtual SVal getLValueVar(const GRState *state, const VarDecl *vd) = 0; - virtual SVal getLValueString(const GRState* St, const StringLiteral* S) = 0; + virtual SVal getLValueString(const GRState *state, + const StringLiteral* sl) = 0; - virtual SVal getLValueCompoundLiteral(const GRState* St, - const CompoundLiteralExpr* CL) = 0; + virtual SVal getLValueCompoundLiteral(const GRState *state, + const CompoundLiteralExpr* cl) = 0; - virtual SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, - SVal Base) = 0; + virtual SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* decl, + SVal base) = 0; - virtual SVal getLValueField(const GRState* St, SVal Base, + virtual SVal getLValueField(const GRState *state, SVal base, const FieldDecl* D) = 0; - virtual SVal getLValueElement(const GRState* St, QualType elementType, - SVal Base, SVal Offset) = 0; + virtual SVal getLValueElement(const GRState *state, QualType elementType, + SVal base, SVal offset) = 0; - virtual SVal getSizeInElements(const GRState* St, const MemRegion* R) { + // FIXME: Make out-of-line. + virtual SVal getSizeInElements(const GRState *state, const MemRegion *region){ return UnknownVal(); } /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit /// conversions between arrays and pointers. virtual SVal ArrayToPointer(Loc Array) = 0; - class CastResult { - const GRState* State; - const MemRegion* R; + const GRState *state; + const MemRegion *region; public: - const GRState* getState() const { return State; } - const MemRegion* getRegion() const { return R; } - CastResult(const GRState* s, const MemRegion* r = 0) : State(s), R(r) {} + const GRState *getState() const { return state; } + const MemRegion* getRegion() const { return region; } + CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){} }; /// 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, + virtual CastResult CastRegion(const GRState *state, const MemRegion *region, QualType CastToTy); /// EvalBinOp - Perform pointer arithmetic. - virtual SVal EvalBinOp(const GRState *state, - BinaryOperator::Opcode Op, Loc L, NonLoc R) { + virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op, + Loc lhs, NonLoc rhs) { return UnknownVal(); } @@ -147,24 +148,27 @@ public: /// method returns NULL. virtual const MemRegion* getSelfRegion(Store store) = 0; - virtual Store - RemoveDeadBindings(const GRState* state, Stmt* Loc, SymbolReaper& SymReaper, - llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; + virtual Store RemoveDeadBindings(const GRState *state, + Stmt* Loc, SymbolReaper& SymReaper, + llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; - virtual const GRState* BindDecl(const GRState* St, const VarDecl* VD, - SVal InitVal) = 0; + virtual const GRState *BindDecl(const GRState *state, const VarDecl *vd, + SVal initVal) = 0; - virtual const GRState* BindDeclWithNoInit(const GRState* St, - const VarDecl* VD) = 0; + virtual const GRState *BindDeclWithNoInit(const GRState *state, + const VarDecl *vd) = 0; - virtual const GRState* setExtent(const GRState* St, - const MemRegion* R, SVal Extent) { - return St; + // FIXME: Make out-of-line. + virtual const GRState *setExtent(const GRState *state, + const MemRegion *region, SVal extent) { + return state; } - virtual const GRState* setDefaultValue(const GRState* St, - const MemRegion* R, SVal V) { - return St; + // FIXME: Make out-of-line. + virtual const GRState *setDefaultValue(const GRState *state, + const MemRegion *region, + SVal val) { + return state; } virtual void print(Store store, std::ostream& Out, @@ -174,13 +178,14 @@ public: public: virtual ~BindingsHandler(); virtual bool HandleBinding(StoreManager& SMgr, Store store, - const MemRegion* R, SVal val) = 0; + const MemRegion *region, SVal val) = 0; }; /// iterBindings - Iterate over the bindings in the Store. virtual void iterBindings(Store store, BindingsHandler& f) = 0; }; +// FIXME: Do we still need this? /// SubRegionMap - An abstract interface that represents a queryable map /// between MemRegion objects and their subregions. class SubRegionMap { @@ -193,13 +198,14 @@ public: virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0; }; - virtual bool iterSubRegions(const MemRegion* R, Visitor& V) const = 0; + virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0; }; - + +// FIXME: Do we need to pass GRStateManager anymore? StoreManager *CreateBasicStoreManager(GRStateManager& StMgr); StoreManager *CreateRegionStoreManager(GRStateManager& StMgr); StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr); - + } // end clang namespace #endif diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index ba4c021475..fcb405d2d2 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -45,15 +45,14 @@ public: ~BasicStoreManager() {} - SubRegionMap* getSubRegionMap(const GRState *state) { + SubRegionMap *getSubRegionMap(const GRState *state) { return new BasicStoreSubRegionMap(); } SVal Retrieve(const GRState *state, Loc loc, QualType T = QualType()); - const GRState* Bind(const GRState* St, Loc L, SVal V) { - Store store = BindInternal(St->getStore(), L, V); - return StateMgr.MakeStateWithStore(St, store); + const GRState *Bind(const GRState *state, Loc L, SVal V) { + return state->makeWithStore(BindInternal(state->getStore(), L, V)); } Store scanForIvars(Stmt *B, const Decl* SelfDecl, Store St); @@ -67,19 +66,19 @@ public: return Loc::MakeVal(MRMgr.getVarRegion(VD)); } - const GRState* BindCompoundLiteral(const GRState* St, - const CompoundLiteralExpr* CL, - SVal V) { - return St; + const GRState *BindCompoundLiteral(const GRState *state, + const CompoundLiteralExpr* cl, + SVal val) { + return state; } - SVal getLValueVar(const GRState* St, const VarDecl* VD); - SVal getLValueString(const GRState* St, const StringLiteral* S); - SVal getLValueCompoundLiteral(const GRState* St, + SVal getLValueVar(const GRState *state, const VarDecl* VD); + SVal getLValueString(const GRState *state, const StringLiteral* S); + SVal getLValueCompoundLiteral(const GRState *state, const CompoundLiteralExpr* CL); - SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base); - SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D); - SVal getLValueElement(const GRState* St, QualType elementType, + SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base); + SVal getLValueField(const GRState *state, SVal Base, const FieldDecl* D); + SVal getLValueElement(const GRState *state, QualType elementType, SVal Base, SVal Offset); /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit @@ -92,23 +91,19 @@ public: const MemRegion* getSelfRegion(Store) { return SelfRegion; } /// RemoveDeadBindings - Scans a BasicStore of 'state' for dead values. - /// It returns a new Store with these values removed, and populates LSymbols - /// and DSymbols with the known set of live and dead symbols respectively. - Store - RemoveDeadBindings(const GRState* state, Stmt* Loc, + /// It returns a new Store with these values removed. + Store RemoveDeadBindings(const GRState *state, Stmt* Loc, SymbolReaper& SymReaper, llvm::SmallVectorImpl<const MemRegion*>& RegionRoots); void iterBindings(Store store, BindingsHandler& f); - const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal) { - Store store = BindDeclInternal(St->getStore(), VD, &InitVal); - return StateMgr.MakeStateWithStore(St, store); + const GRState *BindDecl(const GRState *state, const VarDecl* VD, SVal InitVal) { + return state->makeWithStore(BindDeclInternal(state->getStore(),VD, &InitVal)); } - const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) { - Store store = BindDeclInternal(St->getStore(), VD, 0); - return StateMgr.MakeStateWithStore(St, store); + const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl* VD) { + return state->makeWithStore(BindDeclInternal(state->getStore(), VD, 0)); } Store BindDeclInternal(Store store, const VarDecl* VD, SVal* InitVal); @@ -130,21 +125,21 @@ StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) { return new BasicStoreManager(StMgr); } -SVal BasicStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) { +SVal BasicStoreManager::getLValueVar(const GRState *state, const VarDecl* VD) { return Loc::MakeVal(MRMgr.getVarRegion(VD)); } -SVal BasicStoreManager::getLValueString(const GRState* St, +SVal BasicStoreManager::getLValueString(const GRState *state, const StringLiteral* S) { return Loc::MakeVal(MRMgr.getStringRegion(S)); } -SVal BasicStoreManager::getLValueCompoundLiteral(const GRState* St, +SVal BasicStoreManager::getLValueCompoundLiteral(const GRState *state, const CompoundLiteralExpr* CL){ return Loc::MakeVal(MRMgr.getCompoundLiteralRegion(CL)); } -SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D, +SVal BasicStoreManager::getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base) { if (Base.isUnknownOrUndef()) @@ -162,7 +157,7 @@ SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D, return UnknownVal(); } -SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base, +SVal BasicStoreManager::getLValueField(const GRState *state, SVal Base, const FieldDecl* D) { if (Base.isUnknownOrUndef()) @@ -194,7 +189,7 @@ SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base, return Loc::MakeVal(MRMgr.getFieldRegion(D, BaseR)); } -SVal BasicStoreManager::getLValueElement(const GRState* St, +SVal BasicStoreManager::getLValueElement(const GRState *state, QualType elementType, SVal Base, SVal Offset) { @@ -274,7 +269,7 @@ static bool isHigherOrderRawPtr(QualType T, ASTContext &C) { } } -SVal BasicStoreManager::Retrieve(const GRState* state, Loc loc, QualType T) { +SVal BasicStoreManager::Retrieve(const GRState *state, Loc loc, QualType T) { if (isa<UnknownVal>(loc)) return UnknownVal(); @@ -390,7 +385,7 @@ Store BasicStoreManager::Remove(Store store, Loc loc) { } Store -BasicStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc, +BasicStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc, SymbolReaper& SymReaper, llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) { diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp index e0e478c307..20e4d1f8a9 100644 --- a/lib/Analysis/GRState.cpp +++ b/lib/Analysis/GRState.cpp @@ -69,8 +69,7 @@ const GRState* GRStateManager::Unbind(const GRState* St, Loc LV) { } const GRState* GRStateManager::getInitialState() { - - GRState StateImpl(EnvMgr.getInitialEnvironment(), + GRState StateImpl(this, EnvMgr.getInitialEnvironment(), StoreMgr->getInitialStore(), GDMFactory.GetEmptyMap()); @@ -92,14 +91,12 @@ const GRState* GRStateManager::getPersistentState(GRState& State) { return I; } -const GRState* GRStateManager::MakeStateWithStore(const GRState* St, - Store store) { - GRState NewSt = *St; +const GRState* GRState::makeWithStore(Store store) const { + GRState NewSt = *this; NewSt.St = store; - return getPersistentState(NewSt); + return Mgr->getPersistentState(NewSt); } - //===----------------------------------------------------------------------===// // State pretty-printing. //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index af141892e0..ee62d395e8 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -200,36 +200,32 @@ public: SubRegionMap* getSubRegionMap(const GRState *state); - const GRState* BindCompoundLiteral(const GRState* St, - const CompoundLiteralExpr* CL, SVal V); - /// getLValueString - Returns an SVal representing the lvalue of a /// StringLiteral. Within RegionStore a StringLiteral has an /// associated StringRegion, and the lvalue of a StringLiteral is /// the lvalue of that region. - SVal getLValueString(const GRState* St, const StringLiteral* S); + SVal getLValueString(const GRState *state, const StringLiteral* S); /// getLValueCompoundLiteral - Returns an SVal representing the /// lvalue of a compound literal. Within RegionStore a compound /// literal has an associated region, and the lvalue of the /// compound literal is the lvalue of that region. - SVal getLValueCompoundLiteral(const GRState* St, const CompoundLiteralExpr*); + SVal getLValueCompoundLiteral(const GRState *state, const CompoundLiteralExpr*); /// getLValueVar - Returns an SVal that represents the lvalue of a /// variable. Within RegionStore a variable has an associated /// VarRegion, and the lvalue of the variable is the lvalue of that region. - SVal getLValueVar(const GRState* St, const VarDecl* VD); + SVal getLValueVar(const GRState *state, const VarDecl* VD); - SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base); + SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base); - SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D); + SVal getLValueField(const GRState *state, SVal Base, const FieldDecl* D); - SVal getLValueFieldOrIvar(const GRState* St, SVal Base, const Decl* D); + SVal getLValueFieldOrIvar(const GRState *state, SVal Base, const Decl* D); - SVal getLValueElement(const GRState* St, QualType elementType, + SVal getLValueElement(const GRState *state, QualType elementType, SVal Base, SVal Offset); - SVal getSizeInElements(const GRState* St, const MemRegion* R); /// ArrayToPointer - Emulates the "decay" of an array to a pointer /// type. 'Array' represents the lvalue of the array being decayed @@ -239,27 +235,13 @@ public: /// casts from arrays to pointers. SVal ArrayToPointer(Loc Array); - CastResult CastRegion(const GRState* state, const MemRegion* R, + CastResult CastRegion(const GRState *state, const MemRegion* R, QualType CastToTy); - SVal EvalBinOp(const GRState *state,BinaryOperator::Opcode Op,Loc L,NonLoc R); + SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,Loc L,NonLoc R); - /// The high level logic for this method is this: - /// Retrieve (L) - /// if L has binding - /// return L's binding - /// else if L is in killset - /// return unknown - /// else - /// if L is on stack or heap - /// return undefined - /// else - /// return symbolic - SVal Retrieve(const GRState* state, Loc L, QualType T = QualType()); - const GRState* Bind(const GRState* St, Loc LV, SVal V); - Store Remove(Store store, Loc LV); Store getInitialStore() { return RBFactory.GetEmptyMap().getRoot(); } @@ -279,59 +261,113 @@ public: return SelfRegion; } - /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values. - /// It returns a new Store with these values removed, and populates LSymbols - // and DSymbols with the known set of live and dead symbols respectively. - Store RemoveDeadBindings(const GRState* state, Stmt* Loc, - SymbolReaper& SymReaper, - llvm::SmallVectorImpl<const MemRegion*>& RegionRoots); - const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal); + + //===-------------------------------------------------------------------===// + // Binding values to regions. + //===-------------------------------------------------------------------===// - const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) { - return St; - } + const GRState *Bind(const GRState *state, Loc LV, SVal V); - const GRState* setExtent(const GRState* St, const MemRegion* R, SVal Extent); - const GRState* setCastType(const GRState* St, const MemRegion* R, QualType T); + const GRState *BindCompoundLiteral(const GRState *state, + const CompoundLiteralExpr* CL, SVal V); + + const GRState *BindDecl(const GRState *state, const VarDecl* VD, SVal InitVal); - static inline RegionBindingsTy GetRegionBindings(Store store) { - return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store)); + const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl* VD) { + return state; } - void print(Store store, std::ostream& Out, const char* nl, const char *sep); + /// BindStruct - Bind a compound value to a structure. + const GRState *BindStruct(const GRState *, const TypedRegion* R, SVal V); + + const GRState *BindArray(const GRState *state, const TypedRegion* R, SVal V); + + /// KillStruct - Set the entire struct to unknown. + const GRState *KillStruct(const GRState *state, const TypedRegion* R); - void iterBindings(Store store, BindingsHandler& f) { - // FIXME: Implement. - } - const GRState* setDefaultValue(const GRState* St, const MemRegion* R, SVal V); -private: - const GRState* BindArray(const GRState* St, const TypedRegion* R, SVal V); + const GRState *setDefaultValue(const GRState *state, const MemRegion* R, SVal V); + Store Remove(Store store, Loc LV); + + //===------------------------------------------------------------------===// + // Loading values from regions. + //===------------------------------------------------------------------===// + + /// The high level logic for this method is this: + /// Retrieve (L) + /// if L has binding + /// return L's binding + /// else if L is in killset + /// return unknown + /// else + /// if L is on stack or heap + /// return undefined + /// else + /// return symbolic + SVal Retrieve(const GRState *state, Loc L, QualType T = QualType()); + /// Retrieve the values in a struct and return a CompoundVal, used when doing /// struct copy: /// struct s x, y; /// x = y; /// y's value is retrieved by this method. - SVal RetrieveStruct(const GRState* St, const TypedRegion* R); + SVal RetrieveStruct(const GRState *St, const TypedRegion* R); + + SVal RetrieveArray(const GRState *St, const TypedRegion* R); + + //===------------------------------------------------------------------===// + // State pruning. + //===------------------------------------------------------------------===// + + /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values. + /// It returns a new Store with these values removed. + Store RemoveDeadBindings(const GRState *state, Stmt* Loc, SymbolReaper& SymReaper, + llvm::SmallVectorImpl<const MemRegion*>& RegionRoots); - SVal RetrieveArray(const GRState* St, const TypedRegion* R); + //===------------------------------------------------------------------===// + // Region "extents". + //===------------------------------------------------------------------===// + + const GRState *setExtent(const GRState *state, const MemRegion* R, SVal Extent); + SVal getSizeInElements(const GRState *state, const MemRegion* R); - const GRState* BindStruct(const GRState* St, const TypedRegion* R, SVal V); + //===------------------------------------------------------------------===// + // Region "views". + //===------------------------------------------------------------------===// + + const GRState *AddRegionView(const GRState *state, const MemRegion* View, + const MemRegion* Base); - /// KillStruct - Set the entire struct to unknown. - const GRState* KillStruct(const GRState* St, const TypedRegion* R); + const GRState *RemoveRegionView(const GRState *state, const MemRegion* View, + const MemRegion* Base); + //===------------------------------------------------------------------===// // Utility methods. - BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); } - ASTContext& getContext() { return StateMgr.getContext(); } + //===------------------------------------------------------------------===// + + const GRState *setCastType(const GRState *state, const MemRegion* R, QualType T); + + static inline RegionBindingsTy GetRegionBindings(Store store) { + return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store)); + } + + void print(Store store, std::ostream& Out, const char* nl, const char *sep); - SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); } + void iterBindings(Store store, BindingsHandler& f) { + // FIXME: Implement. + } - const GRState* AddRegionView(const GRState* St, - const MemRegion* View, const MemRegion* Base); - const GRState* RemoveRegionView(const GRState* St, - const MemRegion* View, const MemRegion* Base); + // FIXME: Remove. + BasicValueFactory& getBasicVals() { + return StateMgr.getBasicVals(); + } + + // FIXME: Remove. + ASTContext& getContext() { return StateMgr.getContext(); } + + // FIXME: Use ValueManager? + SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); } }; } // end anonymous namespace @@ -371,7 +407,7 @@ SubRegionMap* RegionStoreManager::getSubRegionMap(const GRState *state) { /// StringLiteral. Within RegionStore a StringLiteral has an /// associated StringRegion, and the lvalue of a StringLiteral is the /// lvalue of that region. -SVal RegionStoreManager::getLValueString(const GRState* St, +SVal RegionStoreManager::getLValueString(const GRState *St, const StringLiteral* S) { return loc::MemRegionVal(MRMgr.getStringRegion(S)); } @@ -379,7 +415,7 @@ SVal RegionStoreManager::getLValueString(const GRState* St, /// getLValueVar - Returns an SVal that represents the lvalue of a /// variable. Within RegionStore a variable has an associated /// VarRegion, and the lvalue of the variable is the lvalue of that region. -SVal RegionStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) { +SVal RegionStoreManager::getLValueVar(const GRState *St, const VarDecl* VD) { return loc::MemRegionVal(MRMgr.getVarRegion(VD)); } @@ -388,22 +424,22 @@ SVal RegionStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) { /// has an associated region, and the lvalue of the compound literal /// is the lvalue of that region. SVal -RegionStoreManager::getLValueCompoundLiteral(const GRState* St, +RegionStoreManager::getLValueCompoundLiteral(const GRState *St, const CompoundLiteralExpr* CL) { return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL)); } -SVal RegionStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D, +SVal RegionStoreManager::getLValueIvar(const GRState *St, const ObjCIvarDecl* D, SVal Base) { return getLValueFieldOrIvar(St, Base, D); } -SVal RegionStoreManager::getLValueField(const GRState* St, SVal Base, +SVal RegionStoreManager::getLValueField(const GRState *St, SVal Base, const FieldDecl* D) { return getLValueFieldOrIvar(St, Base, D); } -SVal RegionStoreManager::getLValueFieldOrIvar(const GRState* St, SVal Base, +SVal RegionStoreManager::getLValueFieldOrIvar(const GRState *St, SVal Base, const Decl* D) { if (Base.isUnknownOrUndef()) return Base; @@ -440,7 +476,7 @@ SVal RegionStoreManager::getLValueFieldOrIvar(const GRState* St, SVal Base, return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR)); } -SVal RegionStoreManager::getLValueElement(const GRState* St, +SVal RegionStoreManager::getLValueElement(const GRState *St, QualType elementType, SVal Base, SVal Offset) { @@ -524,7 +560,7 @@ SVal RegionStoreManager::getLValueElement(const GRState* St, // Extents for regions. //===----------------------------------------------------------------------===// -SVal RegionStoreManager::getSizeInElements(const GRState* St, +SVal RegionStoreManager::getSizeInElements(const GRState *state, const MemRegion* R) { if (const VarRegion* VR = dyn_cast<VarRegion>(R)) { // Get the type of the variable. @@ -539,8 +575,7 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St, return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false); } - GRStateRef state(St, StateMgr); - const QualType* CastTy = state.get<RegionCasts>(VR); + const QualType* CastTy = state->get<RegionCasts>(VR); // If the VarRegion is cast to other type, compute the size with respect to // that type. @@ -586,10 +621,10 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St, return UnknownVal(); } -const GRState* RegionStoreManager::setExtent(const GRState* St, - const MemRegion* R, SVal Extent) { - GRStateRef state(St, StateMgr); - return state.set<RegionExtents>(R, Extent); +const GRState *RegionStoreManager::setExtent(const GRState *state, + const MemRegion *region, + SVal extent) { + return state->set<RegionExtents>(region, extent); } //===----------------------------------------------------------------------===// @@ -624,7 +659,7 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) { } RegionStoreManager::CastResult -RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R, +RegionStoreManager::CastRegion(const GRState *state, const MemRegion* R, QualType CastToTy) { ASTContext& Ctx = StateMgr.getContext(); @@ -720,9 +755,9 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state, } else if (const AllocaRegion *AR = dyn_cast<AllocaRegion>(MR)) { // Get the alloca region's current cast type. - GRStateRef StRef(state, StateMgr); - GRStateTrait<RegionCasts>::lookup_type T = StRef.get<RegionCasts>(AR); + + GRStateTrait<RegionCasts>::lookup_type T = state->get<RegionCasts>(AR); assert( |