diff options
Diffstat (limited to 'include/clang/Analysis')
-rw-r--r-- | include/clang/Analysis/PathSensitive/ConstraintManager.h | 21 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/Environment.h | 25 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 57 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h | 6 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRState.h | 573 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRTransferFuncs.h | 8 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/MemRegion.h | 2 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/SVals.h | 4 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/Store.h | 107 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/SymbolManager.h | 17 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/ValueManager.h | 2 |
11 files changed, 414 insertions, 408 deletions
diff --git a/include/clang/Analysis/PathSensitive/ConstraintManager.h b/include/clang/Analysis/PathSensitive/ConstraintManager.h index c8e5e85..eb519e0 100644 --- a/include/clang/Analysis/PathSensitive/ConstraintManager.h +++ b/include/clang/Analysis/PathSensitive/ConstraintManager.h @@ -30,26 +30,25 @@ class SVal; class ConstraintManager { public: virtual ~ConstraintManager(); - virtual const GRState* Assume(const GRState* St, SVal Cond, - bool Assumption, bool& isFeasible) = 0; + virtual const GRState *Assume(const GRState *state, SVal Cond, + bool Assumption) = 0; - virtual const GRState* AssumeInBound(const GRState* St, SVal Idx, - SVal UpperBound, bool Assumption, - bool& isFeasible) = 0; + virtual const GRState *AssumeInBound(const GRState *state, SVal Idx, + SVal UpperBound, bool Assumption) = 0; - virtual const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) - const = 0; + virtual const llvm::APSInt* getSymVal(const GRState *state, + SymbolRef sym) const = 0; - virtual bool isEqual(const GRState* St, SymbolRef sym, + virtual bool isEqual(const GRState *state, SymbolRef sym, const llvm::APSInt& V) const = 0; - virtual const GRState* RemoveDeadBindings(const GRState* St, + virtual const GRState *RemoveDeadBindings(const GRState *state, SymbolReaper& SymReaper) = 0; - virtual void print(const GRState* St, std::ostream& Out, + virtual void print(const GRState *state, std::ostream& Out, const char* nl, const char *sep) = 0; - virtual void EndPath(const GRState* St) {} + virtual void EndPath(const GRState *state) {} /// canReasonAbout - Not all ConstraintManagers can accurately reason about /// all SVal values. This method returns true if the ConstraintManager can diff --git a/include/clang/Analysis/PathSensitive/Environment.h b/include/clang/Analysis/PathSensitive/Environment.h index fde8b16..0fc49f5 100644 --- a/include/clang/Analysis/PathSensitive/Environment.h +++ b/include/clang/Analysis/PathSensitive/Environment.h @@ -30,13 +30,12 @@ class EnvironmentManager; class BasicValueFactory; class LiveVariables; -class Environment : public llvm::FoldingSetNode { +class Environment { private: - friend class EnvironmentManager; // Type definitions. - typedef llvm::ImmutableMap<Stmt*,SVal> BindingsTy; + typedef llvm::ImmutableMap<const Stmt*,SVal> BindingsTy; // Data. BindingsTy SubExprBindings; @@ -55,25 +54,25 @@ public: beb_iterator beb_begin() const { return BlkExprBindings.begin(); } beb_iterator beb_end() const { return BlkExprBindings.end(); } - SVal LookupSubExpr(Stmt* E) const { + SVal LookupSubExpr(const Stmt* E) const { const SVal* X = SubExprBindings.lookup(cast<Expr>(E)); return X ? *X : UnknownVal(); } - SVal LookupBlkExpr(Stmt* E) const { + SVal LookupBlkExpr(const Stmt* E) const { const SVal* X = BlkExprBindings.lookup(E); return X ? *X : UnknownVal(); } - SVal LookupExpr(Stmt* E) const { + SVal LookupExpr(const Stmt* E) const { const SVal* X = SubExprBindings.lookup(E); if (X) return *X; X = BlkExprBindings.lookup(E); return X ? *X : UnknownVal(); } - SVal GetSVal(Stmt* Ex, BasicValueFactory& BasicVals) const; - SVal GetBlkExprSVal(Stmt* Ex, BasicValueFactory& BasicVals) const; + SVal GetSVal(const Stmt* Ex, BasicValueFactory& BasicVals) const; + SVal GetBlkExprSVal(const Stmt* Ex, BasicValueFactory& BasicVals) const; /// Profile - Profile the contents of an Environment object for use /// in a FoldingSet. @@ -109,19 +108,19 @@ public: /// removed. This method only removes bindings for block-level expressions. /// Using this method on a non-block level expression will return the /// same environment object. - Environment RemoveBlkExpr(const Environment& Env, Stmt* E) { + Environment RemoveBlkExpr(const Environment& Env, const Stmt* E) { return Environment(Env.SubExprBindings, F.Remove(Env.BlkExprBindings, E)); } - Environment RemoveSubExpr(const Environment& Env, Stmt* E) { + Environment RemoveSubExpr(const Environment& Env, const Stmt* E) { return Environment(F.Remove(Env.SubExprBindings, E), Env.BlkExprBindings); } - Environment AddBlkExpr(const Environment& Env, Stmt* E, SVal V) { + Environment AddBlkExpr(const Environment& Env, const Stmt *E, SVal V) { return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V)); } - Environment AddSubExpr(const Environment& Env, Stmt* E, SVal V) { + Environment AddSubExpr(const Environment& Env, const Stmt *E, SVal V) { return Environment(F.Add(Env.SubExprBindings, E, V), Env.BlkExprBindings); } @@ -136,7 +135,7 @@ public: return Environment(F.GetEmptyMap(), F.GetEmptyMap()); } - Environment BindExpr(const Environment& Env, Stmt* E, SVal V, + Environment BindExpr(const Environment& Env, const Stmt* E, SVal V, bool isBlkExpr, bool Invalidate); Environment diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 2068b1b..4af8a7c 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -477,67 +477,14 @@ public: const SymbolManager& getSymbolManager() const { return SymMgr; } protected: - const GRState* GetState(NodeTy* N) { return N == EntryNode ? CleanedState : N->getState(); } -public: - - const GRState* BindExpr(const GRState* St, Expr* Ex, SVal V) { - return StateMgr.BindExpr(St, Ex, V); - } - - const GRState* BindExpr(const GRState* St, const Expr* Ex, SVal V) { - return BindExpr(St, const_cast<Expr*>(Ex), V); - } - -protected: - - const GRState* BindBlkExpr(const GRState* St, Expr* Ex, SVal V) { - return StateMgr.BindExpr(St, Ex, V, true, false); - } - - const GRState* BindLoc(const GRState* St, Loc LV, SVal V) { - return StateMgr.BindLoc(St, LV, V); - } - - SVal GetSVal(const GRState* St, Stmt* Ex) { - return StateMgr.GetSVal(St, Ex); - } - - SVal GetSVal(const GRState* St, const Stmt* Ex) { - return GetSVal(St, const_cast<Stmt*>(Ex)); - } - - SVal GetBlkExprSVal(const GRState* St, Stmt* Ex) { - return StateMgr.GetBlkExprSVal(St, Ex); - } - - SVal GetSVal(const GRState* St, Loc LV, QualType T = QualType()) { - return StateMgr.GetSVal(St, LV, T); - } - +public: inline NonLoc MakeConstantVal(uint64_t X, Expr* Ex) { return NonLoc::MakeVal(getBasicVals(), X, Ex->getType()); - } - - /// Assume - Create new state by assuming that a given expression - /// is true or false. - const GRState* Assume(const GRState* St, SVal Cond, bool Assumption, - bool& isFeasible) { - return StateMgr.Assume(St, Cond, Assumption, isFeasible); - } - - const GRState* Assume(const GRState* St, Loc Cond, bool Assumption, - bool& isFeasible) { - return StateMgr.Assume(St, Cond, Assumption, isFeasible); - } - - const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound, - bool Assumption, bool& isFeasible) { - return StateMgr.AssumeInBound(St, Idx, UpperBound, Assumption, isFeasible); - } + } public: NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, const GRState* St, diff --git a/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h b/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h index 6c23745..0f3a137 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h @@ -83,11 +83,9 @@ public: Dst.Add(Pred); } } - - GRStateRef getState() { - return GRStateRef(state, Eng.getStateManager()); - } + const GRState *getState() { return state; } + GRStateManager& getStateManager() { return Eng.getStateManager(); } diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index d61feea..6f95c6f 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(); } @@ -142,10 +155,119 @@ public: typedef Environment::beb_iterator beb_iterator; beb_iterator beb_begin() const { return Env.beb_begin(); } beb_iterator beb_end() const { return Env.beb_end(); } + + BasicValueFactory &getBasicVals() const; + SymbolManager &getSymbolManager() const; + GRTransferFuncs &getTransferFuncs() const; + + //==---------------------------------------------------------------------==// + // Constraints on values. + //==---------------------------------------------------------------------==// + // + // Each GRState records constraints on symbolic values. These constraints + // are managed using the ConstraintManager associated with a GRStateManager. + // As constraints gradually accrue on symbolic values, added constraints + // may conflict and indicate that a state is infeasible (as no real values + // could satisfy all the constraints). This is the principal mechanism + // for modeling path-sensitivity in GRExprEngine/GRState. + // + // Various "Assume" methods form the interface for adding constraints to + // symbolic values. A call to "Assume" indicates an assumption being placed + // on one or symbolic values. Assume methods take the following inputs: + // + // (1) A GRState object representing the current state. + // + // (2) The assumed constraint (which is specific to a given "Assume" method). + // + // (3) A binary value "Assumption" that indicates whether the constraint is + // assumed to be true or false. + // + // The output of "Assume" are two values: + // + // (a) "isFeasible" is set to true or false to indicate whether or not + // the assumption is feasible. + // + // (b) A new GRState object with the added constraints. + // + // FIXME: (a) should probably disappear since it is redundant with (b). + // (i.e., (b) could just be set to NULL). + // + + const GRState *assume(SVal condition, bool assumption) const; + + const GRState *assumeInBound(SVal idx, SVal upperBound, + bool assumption) const; + + //==---------------------------------------------------------------------==// + // Binding and retrieving values to/from the environment and symbolic store. + //==---------------------------------------------------------------------==// + + /// BindCompoundLiteral - Return the state that has the bindings currently + /// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region + /// for the compound literal and 'BegInit' and 'EndInit' represent an + /// array of initializer values. + const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL, + SVal V) const; + + const GRState *bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr, + bool Invalidate) const; + + const GRState *bindExpr(const Stmt* Ex, SVal V, bool Invalidate = true) const; + + const GRState *bindBlkExpr(const Stmt *Ex, SVal V) const { + return bindExpr(Ex, V, true, false); + } + + const GRState *bindLoc(Loc location, SVal V) const; + + const GRState *bindLoc(SVal location, SVal V) const; + + const GRState *unbindLoc(Loc LV) const; + + /// Get the lvalue for a variable reference. + SVal getLValue(const VarDecl *decl) const; + + /// Get the lvalue for a StringLiteral. + SVal getLValue(const StringLiteral *literal) const; + + SVal getLValue(const CompoundLiteralExpr *literal) const; + + /// Get the lvalue for an ivar reference. + SVal getLValue(const ObjCIvarDecl *decl, SVal base) const; + + /// Get the lvalue for a field reference. + SVal getLValue(SVal Base, const FieldDecl *decl) const; + + /// Get the lvalue for an array index. + SVal getLValue(QualType ElementType, SVal Base, SVal Idx) const; + + const llvm::APSInt *getSymVal(SymbolRef sym) const; + + SVal getSVal(const Stmt* Ex) const; + + SVal getBlkExprSVal(const Stmt* Ex) const; + + SVal getSValAsScalarOrLoc(const Stmt *Ex) const; + + SVal getSVal(Loc LV, QualType T = QualType()) const; + + SVal getSVal(const MemRegion* R) const; + + SVal getSValAsScalarOrLoc(const MemRegion *R) const; + + bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const; + + template <typename CB> CB scanReachableSymbols(SVal val) const; + + //==---------------------------------------------------------------------==// + // Accessing the Generic Data Map (GDM). + //==---------------------------------------------------------------------==// - // 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 +281,29 @@ 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 *remove(typename GRStateTrait<T>::key_type K) const; + + template<typename T> + const GRState *remove(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::context_type C) 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()); @@ -172,11 +317,14 @@ public: virtual void Print(std::ostream& Out, const GRState* state, const char* nl, const char* sep) = 0; }; + + // Pretty-printing. + void print(std::ostream& Out, const char *nl = "\n", + const char *sep = "") const; - void print(std::ostream& Out, StoreManager& StoreMgr, - ConstraintManager& ConstraintMgr, - Printer **Beg = 0, Printer **End = 0, - const char* nl = "\n", const char *sep = "") const; + void printStdErr() const; + + void printDOT(std::ostream& Out) const; // Tags used for the Generic Data Map. struct NullDerefTag { @@ -233,11 +381,9 @@ public: // GRStateManager - Factory object for GRStates. //===----------------------------------------------------------------------===// -class GRStateRef; - class GRStateManager { friend class GRExprEngine; - friend class GRStateRef; + friend class GRState; private: EnvironmentManager EnvMgr; @@ -361,15 +507,6 @@ public: // Store manager should return a persistent state. return StoreMgr->BindDeclWithNoInit(St, VD); } - - /// BindCompoundLiteral - Return the state that has the bindings currently - /// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region - /// for the compound literal and 'BegInit' and 'EndInit' represent an - /// array of initializer values. - const GRState* BindCompoundLiteral(const GRState* St, - const CompoundLiteralExpr* CL, SVal V) { - return StoreMgr->BindCompoundLiteral(St, CL, V); - } const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc, SymbolReaper& SymReaper); @@ -391,38 +528,10 @@ public: return StoreMgr->getSelfRegion(state->getStore()); } - // Get the lvalue for a variable reference. - SVal GetLValue(const GRState* St, const VarDecl* D) { - return StoreMgr->getLValueVar(St, D); - } - - // Get the lvalue for a StringLiteral. - SVal GetLValue(const GRState* St, const StringLiteral* E) { - return StoreMgr->getLValueString(St, E); - } - - SVal GetLValue(const GRState* St, const CompoundLiteralExpr* CL) { - return StoreMgr->getLValueCompoundLiteral(St, CL); - } - - // Get the lvalue for an ivar reference. - SVal GetLValue(const GRState* St, const ObjCIvarDecl* D, SVal Base) { - return StoreMgr->getLValueIvar(St, D, Base); - } - - // Get the lvalue for a field reference. - SVal GetLValue(const GRState* St, SVal Base, const FieldDecl* D) { - return StoreMgr->getLValueField(St, Base, D); - } - - // Get the lvalue for an array index. - SVal GetLValue(const GRState* St, QualType ElementType, SVal Base, SVal Idx) { - return StoreMgr->getLValueElement(St, ElementType, Base, Idx); - } +private: - // Methods that query & manipulate the Environment. - - SVal GetSVal(const GRState* St, Stmt* Ex) { + // Methods that query & manipulate the Environment. + SVal GetSVal(const GRState* St, const Stmt* Ex) { return St->getEnvironment().GetSVal(Ex, getBasicVals()); } @@ -435,19 +544,12 @@ public: return UnknownVal(); } - - SVal GetSVal(const GRState* St, const Stmt* Ex) { - return St->getEnvironment().GetSVal(const_cast<Stmt*>(Ex), getBasicVals()); - } - - SVal GetBlkExprSVal(const GRState* St, Stmt* Ex) { + SVal GetBlkExprSVal(const GRState* St, const Stmt* Ex) { return St->getEnvironment().GetBlkExprSVal(Ex, getBasicVals()); } - - - const GRState* BindExpr(const GRState* St, Stmt* Ex, SVal V, + const GRState* BindExpr(const GRState* St, const Stmt* Ex, SVal V, bool isBlkExpr, bool Invalidate) { const Environment& OldEnv = St->getEnvironment(); @@ -461,7 +563,7 @@ public: return getPersistentState(NewSt); } - const GRState* BindExpr(const GRState* St, Stmt* Ex, SVal V, + const GRState* BindExpr(const GRState* St, const Stmt* Ex, SVal V, bool Invalidate = true) { bool isBlkExpr = false; @@ -478,6 +580,8 @@ public: return BindExpr(St, Ex, V, isBlkExpr, Invalidate); } +public: + SVal ArrayToPointer(Loc Array) { return StoreMgr->ArrayToPointer(Array); } @@ -533,13 +637,9 @@ 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); - //==---------------------------------------------------------------------==// // Generic Data Map methods. //==---------------------------------------------------------------------==// @@ -605,56 +705,6 @@ public: return GRStateTrait<T>::MakeContext(p); } - - //==---------------------------------------------------------------------==// - // Constraints on values. - //==---------------------------------------------------------------------==// - // - // Each GRState records constraints on symbolic values. These constraints - // are managed using the ConstraintManager associated with a GRStateManager. - // As constraints gradually accrue on symbolic values, added constraints - // may conflict and indicate that a state is infeasible (as no real values - // could satisfy all the constraints). This is the principal mechanism - // for modeling path-sensitivity in GRExprEngine/GRState. - // - // Various "Assume" methods form the interface for adding constraints to - // symbolic values. A call to "Assume" indicates an assumption being placed - // on one or symbolic values. Assume methods take the following inputs: - // - // (1) A GRState object representing the current state. - // - // (2) The assumed constraint (which is specific to a given "Assume" method). - // - // (3) A binary value "Assumption" that indicates whether the constraint is - // assumed to be true or false. - // - // The output of "Assume" are two values: - // - // (a) "isFeasible" is set to true or false to indicate whether or not - // the assumption is feasible. - // - // (b) A new GRState object with the added constraints. - // - // FIXME: (a) should probably disappear since it is redundant with (b). - // (i.e., (b) could just be set to NULL). - // - - const GRState* Assume(const GRState* St, SVal Cond, bool Assumption, - bool& isFeasible) { - const GRState *state = - ConstraintMgr->Assume(St, Cond, Assumption, isFeasible); - assert(!isFeasible || state); - return isFeasible ? state : NULL; - } - - const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound, - bool Assumption, bool& isFeasible) { - const GRState *state = - ConstraintMgr->AssumeInBound(St, Idx, UpperBound, Assumption, - isFeasible); - assert(!isFeasible || state); - return isFeasible ? state : NULL; - } const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) { return ConstraintMgr->getSymVal(St, sym); @@ -663,157 +713,158 @@ public: void EndPath(const GRState* St) { ConstraintMgr->EndPath(St); } - - bool scanReachableSymbols(SVal val, const GRState* state, - SymbolVisitor& visitor); }; + //===----------------------------------------------------------------------===// -// GRStateRef - A "fat" reference to GRState that also bundles GRStateManager. +// Out-of-line method definitions for GRState. //===----------------------------------------------------------------------===// - -class GRStateRef { - const GRState* St; - GRStateManager* Mgr; -public: - GRStateRef(const GRState* st, GRStateManager& mgr) : St(st), Mgr(&mgr) {} - - const GRState* getState() const { return St; } - operator const GRState*() const { return St; } - GRStateManager& getManager() const { return *Mgr; } - - SVal GetSVal(Expr* Ex) { - return Mgr->GetSVal(St, Ex); - } - - SVal GetBlkExprSVal(Expr* Ex) { - return Mgr->GetBlkExprSVal(St, Ex); - } - - SVal GetSValAsScalarOrLoc(const Expr *Ex) { - return Mgr->GetSValAsScalarOrLoc(St, Ex); - } - - SVal GetSVal(Loc LV, QualType T = QualType()) { - return Mgr->GetSVal(St, LV, T); - } - - SVal GetSVal(const MemRegion* R) { - return Mgr->GetSVal(St, R); - } - - SVal GetSValAsScalarOrLoc(const MemRegion *R) { - return Mgr->GetSValAsScalarOrLoc(St, R); - } - - GRStateRef BindExpr(Stmt* Ex, SVal V, bool isBlkExpr, bool Invalidate) { - return GRStateRef(Mgr->BindExpr(St, Ex, V, isBlkExpr, Invalidate), *Mgr); - } - - GRStateRef BindExpr(Stmt* Ex, SVal V, bool Invalidate = true) { - return GRStateRef(Mgr->BindExpr(St, Ex, V, Invalidate), *Mgr); - } - - GRStateRef BindDecl(const VarDecl* VD, SVal InitVal) { - return GRStateRef(Mgr->BindDecl(St, VD, InitVal), *Mgr); - } - - GRStateRef BindLoc(Loc LV, SVal V) { - return GRStateRef(Mgr->BindLoc(St, LV, V), *Mgr); - } - - GRStateRef BindLoc(SVal LV, SVal V) { - if (!isa<Loc>(LV)) return *this; - return BindLoc(cast<Loc>(LV), V); - } - - GRStateRef Unbind(Loc LV) { - return GRStateRef(Mgr->Unbind(St, LV), *Mgr); - } - - // Trait based GDM dispatch. - template<typename T> - typename GRStateTrait<T>::data_type get() const { - return St->get<T>(); - } - - template<typename T> - typename GRStateTrait<T>::lookup_type - get(typename GRStateTrait<T>::key_type key) const { - return St->get<T>(key); - } - - template<typename T> - GRStateRef set(typename GRStateTrait<T>::data_type D) { - return GRStateRef(Mgr->set<T>(St, D), *Mgr); - } - template <typename T> - typename GRStateTrait<T>::context_type get_context() { - return Mgr->get_context<T>(); - } - - template<typename T> - GRStateRef set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E, - typename GRStateTrait<T>::context_type C) { - return GRStateRef(Mgr->set<T>(St, K, E, C), *Mgr); - } - - template<typename T> - GRStateRef set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E) { - return GRStateRef(Mgr->set<T>(St, K, E, get_context<T>()), *Mgr); - } - - template<typename T> - GRStateRef add(typename GRStateTrait<T>::key_type K) { - return GRStateRef(Mgr->add<T>(St, K, get_context<T>()), *Mgr); - } - - template<typename T> - GRStateRef remove(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) { - return GRStateRef(Mgr->remove<T>(St, K, C), *Mgr); - } - - template<typename T> - GRStateRef remove(typename GRStateTrait<T>::key_type K) { - return GRStateRef(Mgr->remove<T>(St, K, get_context<T>()), *Mgr); - } - - template<typename T> - bool contains(typename GRStateTrait<T>::key_type key) const { - return St->contains<T>(key); - } - - // Lvalue methods. - SVal GetLValue(const VarDecl* VD) { - return Mgr->GetLValue(St, VD); - } - - GRStateRef Assume(SVal Cond, bool Assumption, bool& isFeasible) { - return GRStateRef(Mgr->Assume(St, Cond, Assumption, isFeasible), *Mgr); - } - - template <typename CB> - CB scanReachableSymbols(SVal val) { - CB cb(*this); - Mgr->scanReachableSymbols(val, St, cb); - return cb; - } - - SymbolManager& getSymbolManager() { return Mgr->getSymbolManager(); } - BasicValueFactory& getBasicVals() { return Mgr->getBasicVals(); } - - // Pretty-printing. - void print(std::ostream& Out, const char* nl = "\n", - const char *sep = "") const; - - void printStdErr() const; - - void printDOT(std::ostream& Out) const; -}; +inline const GRState *GRState::assume(SVal Cond, bool Assumption) const { + return Mgr->ConstraintMgr->Assume(this, Cond, Assumption); +} + +inline const GRState *GRState::assumeInBound(SVal Idx, SVal UpperBound, + bool Assumption) const { + return Mgr->ConstraintMgr->AssumeInBound(this, Idx, UpperBound, Assumption); +} + +inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL, + SVal V) const { + return Mgr->StoreMgr->BindCompoundLiteral(this, CL, V); +} + +inline const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr, + bool Invalidate) const { + return Mgr->BindExpr(this, Ex, V, isBlkExpr, Invalidate); +} + +inline const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, + bool Invalidate) const { + return Mgr->BindExpr(this, Ex, V, Invalidate); +} + +inline const GRState *GRState::bindLoc(Loc LV, SVal V) const { + return Mgr->BindLoc(this, LV, V); +} + +inline const GRState *GRState::bindLoc(SVal LV, SVal V) const { + return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V); +} + +inline SVal GRState::getLValue(const VarDecl* VD) const { + return Mgr->StoreMgr->getLValueVar(this, VD); +} + +inline SVal GRState::getLValue(const StringLiteral *literal) const { + return Mgr->StoreMgr->getLValueString(this, literal); +} + +inline SVal GRState::getLValue(const CompoundLiteralExpr *literal) const { + return Mgr->StoreMgr->getLValueCompoundLiteral(this, literal); +} + +inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const { + return Mgr->StoreMgr->getLValueIvar(this, D, Base); +} + +inline SVal GRState::getLValue(SVal Base, const FieldDecl* D) const { + return Mgr->StoreMgr->getLValueField(this, Base, D); +} + +inline SVal GRState::getLValue(QualType ElementType, SVal Base, SVal Idx) const{ + return Mgr->StoreMgr->getLValueElement(this, ElementType, Base, Idx); +} + +inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const { + return Mgr->getSymVal(this, sym); +} + +inline SVal GRState::getSVal(const Stmt* Ex) const { + return Mgr->GetSVal(this, Ex); +} + +inline SVal GRState::getBlkExprSVal(const Stmt* Ex) const { + return Mgr->GetBlkExprSVal(this, Ex); +} + +inline SVal GRState::getSValAsScalarOrLoc(const Stmt *Ex) const { + return Mgr->GetSValAsScalarOrLoc(this, Ex); +} + +inline SVal GRState::getSVal(Loc LV, QualType T) const { + return Mgr->GetSVal(this, LV, T); +} + +inline SVal GRState::getSVal(const MemRegion* R) const { + return Mgr->GetSVal(this, R); +} + +inline SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const { + return Mgr->GetSValAsScalarOrLoc(this, R); +} + +inline BasicValueFactory &GRState::getBasicVals() const { + return Mgr->getBasicVals(); +} + +inline SymbolManager &GRState::getSymbolManager() const { + return Mgr->getSymbolManager(); +} + +inline GRTransferFuncs &GRState::getTransferFuncs() const { + return Mgr->getTransferFuncs(); +} + +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::remove(typename GRStateTrait<T>::key_type K) const { + return Mgr->remove<T>(this, K, get_context<T>()); +} + +template<typename T> +const GRState *GRState::remove(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::context_type C) const { + return Mgr->remove<T>(this, K, C); +} + +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); +} + +template <typename CB> +CB GRState::scanReachableSymbols(SVal val) const { + CB cb(this); + scanReachableSymbols(val, cb); + return cb; +} + +inline const GRState *GRState::unbindLoc(Loc LV) const { + return Mgr->Unbind(this, LV); +} } // end clang namespace diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index 0f353d0..c2f8f5a 100644 --- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -110,11 +110,9 @@ public: // Assumptions. - virtual const GRState* EvalAssume(GRStateManager& VMgr, - const GRState* St, - SVal Cond, bool Assumption, - bool& isFeasible) { - return St; + virtual const GRState* EvalAssume(const GRState *state, + SVal Cond, bool Assumption) { + return state; } }; diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index 0e8da2a..8afcc4c 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -620,7 +620,7 @@ public: /// getElementRegion - Retrieve the memory region associated with the /// associated element type, index, and super region. ElementRegion* getElementRegion(QualType elementType, SVal Idx, - const MemRegion* superRegion); + const MemRegion* superRegion,ASTContext &Ctx); /// getFieldRegion - Retrieve or create the memory region associated with /// a specified FieldDecl. 'superRegion' corresponds to the containing diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h index ee6d4dc..c9d1e25 100644 --- a/include/clang/Analysis/PathSensitive/SVals.h +++ b/include/clang/Analysis/PathSensitive/SVals.h @@ -181,7 +181,7 @@ public: static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T); - static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I); + static NonLoc MakeVal(BasicValueFactory& BasicVals, const IntegerLiteral *I); static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I, bool isUnsigned); @@ -212,7 +212,7 @@ public: static Loc MakeVal(const MemRegion* R); - static Loc MakeVal(AddrLabelExpr* E); + static Loc MakeVal(const AddrLabelExpr* E); static Loc MakeNull(BasicValueFactory &BasicVals); diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 1f081f4..0c5df2e 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,12 +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; }; - -StoreManager* CreateBasicStoreManager(GRStateManager& StMgr); -StoreManager* CreateRegionStoreManager(GRStateManager& StMgr); - + +// 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/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index d424526..d074e30 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -83,19 +83,25 @@ typedef const SymbolData* SymbolRef; class SymbolRegionValue : public SymbolData { const MemRegion *R; + // We may cast the region to another type, so the expected type of the symbol + // may be different from the region's original type. + QualType T; + public: - SymbolRegionValue(SymbolID sym, const MemRegion *r) - : SymbolData(RegionValueKind, sym), R(r) {} + SymbolRegionValue(SymbolID sym, const MemRegion *r, QualType t = QualType()) + : SymbolData(RegionValueKind, sym), R(r), T(t) {} const MemRegion* getRegion() const { return R; } - static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R) { + static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R, + QualType T) { profile.AddInteger((unsigned) RegionValueKind); profile.AddPointer(R); + T.Profile(profile); } virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, R); + Profile(profile, R, T); } QualType getType(ASTContext&) const; @@ -240,7 +246,8 @@ public: static bool canSymbolicate(QualType T); /// Make a unique symbol for MemRegion R according to its kind. - const SymbolRegionValue* getRegionValueSymbol(const MemRegion* R); + const SymbolRegionValue* getRegionValueSymbol(const MemRegion* R, + QualType T = QualType()); const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T, unsigned VisitCount, const void* SymbolTag = 0); diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h index 89af975..b86f4e8 100644 --- a/include/clang/Analysis/PathSensitive/ValueManager.h +++ b/include/clang/Analysis/PathSensitive/ValueManager.h @@ -81,7 +81,7 @@ public: SVal makeZeroArrayIndex(); /// GetRegionValueSymbolVal - make a unique symbol for value of R. - SVal getRegionValueSymbolVal(const MemRegion* R); + SVal getRegionValueSymbolVal(const MemRegion* R, QualType T = QualType()); SVal getConjuredSymbolVal(const Expr *E, unsigned Count); SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count); |