• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //== ProgramState.h - Path-sensitive "State" for tracking values -*- C++ -*--=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines SymbolRef, ExprBindKey, and ProgramState*.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_GR_VALUESTATE_H
15 #define LLVM_CLANG_GR_VALUESTATE_H
16 
17 #include "clang/Basic/LLVM.h"
18 #include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
21 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
22 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
23 #include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
24 #include "llvm/ADT/PointerIntPair.h"
25 #include "llvm/ADT/FoldingSet.h"
26 #include "llvm/ADT/ImmutableMap.h"
27 
28 namespace llvm {
29 class APSInt;
30 class BumpPtrAllocator;
31 }
32 
33 namespace clang {
34 class ASTContext;
35 
36 namespace ento {
37 
38 class CallOrObjCMessage;
39 
40 typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
41                                                        SubEngine&);
42 typedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&);
43 
44 //===----------------------------------------------------------------------===//
45 // ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
46 //===----------------------------------------------------------------------===//
47 
48 template <typename T> struct ProgramStatePartialTrait;
49 
50 template <typename T> struct ProgramStateTrait {
51   typedef typename T::data_type data_type;
GDMIndexProgramStateTrait52   static inline void *GDMIndex() { return &T::TagInt; }
MakeVoidPtrProgramStateTrait53   static inline void *MakeVoidPtr(data_type D) { return (void*) D; }
MakeDataProgramStateTrait54   static inline data_type MakeData(void *const* P) {
55     return P ? (data_type) *P : (data_type) 0;
56   }
57 };
58 
59 /// \class ProgramState
60 /// ProgramState - This class encapsulates:
61 ///
62 ///    1. A mapping from expressions to values (Environment)
63 ///    2. A mapping from locations to values (Store)
64 ///    3. Constraints on symbolic values (GenericDataMap)
65 ///
66 ///  Together these represent the "abstract state" of a program.
67 ///
68 ///  ProgramState is intended to be used as a functional object; that is,
69 ///  once it is created and made "persistent" in a FoldingSet, its
70 ///  values will never change.
71 class ProgramState : public llvm::FoldingSetNode {
72 public:
73   typedef llvm::ImmutableSet<llvm::APSInt*>                IntSetTy;
74   typedef llvm::ImmutableMap<void*, void*>                 GenericDataMap;
75 
76 private:
77   void operator=(const ProgramState& R) const; // Do not implement.
78 
79   friend class ProgramStateManager;
80   friend class ExplodedGraph;
81   friend class ExplodedNode;
82 
83   ProgramStateManager *stateMgr;
84   Environment Env;           // Maps a Stmt to its current SVal.
85   Store store;               // Maps a location to its current value.
86   GenericDataMap   GDM;      // Custom data stored by a client of this class.
87   unsigned refCount;
88 
89   /// makeWithStore - Return a ProgramState with the same values as the current
90   ///  state with the exception of using the specified Store.
91   ProgramStateRef makeWithStore(const StoreRef &store) const;
92 
93   void setStore(const StoreRef &storeRef);
94 
95 public:
96   /// This ctor is used when creating the first ProgramState object.
97   ProgramState(ProgramStateManager *mgr, const Environment& env,
98           StoreRef st, GenericDataMap gdm);
99 
100   /// Copy ctor - We must explicitly define this or else the "Next" ptr
101   ///  in FoldingSetNode will also get copied.
102   ProgramState(const ProgramState &RHS);
103 
104   ~ProgramState();
105 
106   /// Return the ProgramStateManager associated with this state.
getStateManager()107   ProgramStateManager &getStateManager() const { return *stateMgr; }
108 
109   /// getEnvironment - Return the environment associated with this state.
110   ///  The environment is the mapping from expressions to values.
getEnvironment()111   const Environment& getEnvironment() const { return Env; }
112 
113   /// Return the store associated with this state.  The store
114   ///  is a mapping from locations to values.
getStore()115   Store getStore() const { return store; }
116 
117 
118   /// getGDM - Return the generic data map associated with this state.
getGDM()119   GenericDataMap getGDM() const { return GDM; }
120 
setGDM(GenericDataMap gdm)121   void setGDM(GenericDataMap gdm) { GDM = gdm; }
122 
123   /// Profile - Profile the contents of a ProgramState object for use in a
124   ///  FoldingSet.  Two ProgramState objects are considered equal if they
125   ///  have the same Environment, Store, and GenericDataMap.
Profile(llvm::FoldingSetNodeID & ID,const ProgramState * V)126   static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
127     V->Env.Profile(ID);
128     ID.AddPointer(V->store);
129     V->GDM.Profile(ID);
130   }
131 
132   /// Profile - Used to profile the contents of this object for inclusion
133   ///  in a FoldingSet.
Profile(llvm::FoldingSetNodeID & ID)134   void Profile(llvm::FoldingSetNodeID& ID) const {
135     Profile(ID, this);
136   }
137 
138   BasicValueFactory &getBasicVals() const;
139   SymbolManager &getSymbolManager() const;
140 
141   //==---------------------------------------------------------------------==//
142   // Constraints on values.
143   //==---------------------------------------------------------------------==//
144   //
145   // Each ProgramState records constraints on symbolic values.  These constraints
146   // are managed using the ConstraintManager associated with a ProgramStateManager.
147   // As constraints gradually accrue on symbolic values, added constraints
148   // may conflict and indicate that a state is infeasible (as no real values
149   // could satisfy all the constraints).  This is the principal mechanism
150   // for modeling path-sensitivity in ExprEngine/ProgramState.
151   //
152   // Various "assume" methods form the interface for adding constraints to
153   // symbolic values.  A call to 'assume' indicates an assumption being placed
154   // on one or symbolic values.  'assume' methods take the following inputs:
155   //
156   //  (1) A ProgramState object representing the current state.
157   //
158   //  (2) The assumed constraint (which is specific to a given "assume" method).
159   //
160   //  (3) A binary value "Assumption" that indicates whether the constraint is
161   //      assumed to be true or false.
162   //
163   // The output of "assume*" is a new ProgramState object with the added constraints.
164   // If no new state is feasible, NULL is returned.
165   //
166 
167   ProgramStateRef assume(DefinedOrUnknownSVal cond, bool assumption) const;
168 
169   /// This method assumes both "true" and "false" for 'cond', and
170   ///  returns both corresponding states.  It's shorthand for doing
171   ///  'assume' twice.
172   std::pair<ProgramStateRef , ProgramStateRef >
173   assume(DefinedOrUnknownSVal cond) const;
174 
175   ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx,
176                                DefinedOrUnknownSVal upperBound,
177                                bool assumption,
178                                QualType IndexType = QualType()) const;
179 
180   /// Utility method for getting regions.
181   const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
182 
183   //==---------------------------------------------------------------------==//
184   // Binding and retrieving values to/from the environment and symbolic store.
185   //==---------------------------------------------------------------------==//
186 
187   /// BindCompoundLiteral - Return the state that has the bindings currently
188   ///  in this state plus the bindings for the CompoundLiteral.
189   ProgramStateRef bindCompoundLiteral(const CompoundLiteralExpr *CL,
190                                      const LocationContext *LC,
191                                      SVal V) const;
192 
193   /// Create a new state by binding the value 'V' to the statement 'S' in the
194   /// state's environment.
195   ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx,
196                                SVal V, bool Invalidate = true) const;
197 
198   /// Create a new state by binding the value 'V' and location 'locaton' to the
199   /// statement 'S' in the state's environment.
200   ProgramStateRef bindExprAndLocation(const Stmt *S,
201                                           const LocationContext *LCtx,
202                                           SVal location, SVal V) const;
203 
204   ProgramStateRef bindDecl(const VarRegion *VR, SVal V) const;
205 
206   ProgramStateRef bindDeclWithNoInit(const VarRegion *VR) const;
207 
208   ProgramStateRef bindLoc(Loc location, SVal V) const;
209 
210   ProgramStateRef bindLoc(SVal location, SVal V) const;
211 
212   ProgramStateRef bindDefault(SVal loc, SVal V) const;
213 
214   ProgramStateRef unbindLoc(Loc LV) const;
215 
216   /// invalidateRegions - Returns the state with bindings for the given regions
217   ///  cleared from the store. The regions are provided as a continuous array
218   ///  from Begin to End. Optionally invalidates global regions as well.
219   ProgramStateRef invalidateRegions(ArrayRef<const MemRegion *> Regions,
220                                const Expr *E, unsigned BlockCount,
221                                const LocationContext *LCtx,
222                                StoreManager::InvalidatedSymbols *IS = 0,
223                                const CallOrObjCMessage *Call = 0) const;
224 
225   /// enterStackFrame - Returns the state for entry to the given stack frame,
226   ///  preserving the current state.
227   ProgramStateRef enterStackFrame(const LocationContext *callerCtx,
228                                       const StackFrameContext *calleeCtx) const;
229 
230   /// Get the lvalue for a variable reference.
231   Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
232 
233   Loc getLValue(const CompoundLiteralExpr *literal,
234                 const LocationContext *LC) const;
235 
236   /// Get the lvalue for an ivar reference.
237   SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
238 
239   /// Get the lvalue for a field reference.
240   SVal getLValue(const FieldDecl *decl, SVal Base) const;
241 
242   /// Get the lvalue for an array index.
243   SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
244 
245   const llvm::APSInt *getSymVal(SymbolRef sym) const;
246 
247   /// Returns the SVal bound to the statement 'S' in the state's environment.
248   SVal getSVal(const Stmt *S, const LocationContext *LCtx,
249                bool useOnlyDirectBindings = false) const;
250 
251   SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
252 
253   /// \brief Return the value bound to the specified location.
254   /// Returns UnknownVal() if none found.
255   SVal getSVal(Loc LV, QualType T = QualType()) const;
256 
257   /// Returns the "raw" SVal bound to LV before any value simplfication.
258   SVal getRawSVal(Loc LV, QualType T= QualType()) const;
259 
260   /// \brief Return the value bound to the specified location.
261   /// Returns UnknownVal() if none found.
262   SVal getSVal(const MemRegion* R) const;
263 
264   SVal getSValAsScalarOrLoc(const MemRegion *R) const;
265 
266   /// \brief Visits the symbols reachable from the given SVal using the provided
267   /// SymbolVisitor.
268   ///
269   /// This is a convenience API. Consider using ScanReachableSymbols class
270   /// directly when making multiple scans on the same state with the same
271   /// visitor to avoid repeated initialization cost.
272   /// \sa ScanReachableSymbols
273   bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
274 
275   /// \brief Visits the symbols reachable from the SVals in the given range
276   /// using the provided SymbolVisitor.
277   bool scanReachableSymbols(const SVal *I, const SVal *E,
278                             SymbolVisitor &visitor) const;
279 
280   /// \brief Visits the symbols reachable from the regions in the given
281   /// MemRegions range using the provided SymbolVisitor.
282   bool scanReachableSymbols(const MemRegion * const *I,
283                             const MemRegion * const *E,
284                             SymbolVisitor &visitor) const;
285 
286   template <typename CB> CB scanReachableSymbols(SVal val) const;
287   template <typename CB> CB scanReachableSymbols(const SVal *beg,
288                                                  const SVal *end) const;
289 
290   template <typename CB> CB
291   scanReachableSymbols(const MemRegion * const *beg,
292                        const MemRegion * const *end) const;
293 
294   /// Create a new state in which the statement is marked as tainted.
295   ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx,
296                                TaintTagType Kind = TaintTagGeneric) const;
297 
298   /// Create a new state in which the symbol is marked as tainted.
299   ProgramStateRef addTaint(SymbolRef S,
300                                TaintTagType Kind = TaintTagGeneric) const;
301 
302   /// Create a new state in which the region symbol is marked as tainted.
303   ProgramStateRef addTaint(const MemRegion *R,
304                                TaintTagType Kind = TaintTagGeneric) const;
305 
306   /// Check if the statement is tainted in the current state.
307   bool isTainted(const Stmt *S, const LocationContext *LCtx,
308                  TaintTagType Kind = TaintTagGeneric) const;
309   bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const;
310   bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const;
311   bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
312 
313   //==---------------------------------------------------------------------==//
314   // Accessing the Generic Data Map (GDM).
315   //==---------------------------------------------------------------------==//
316 
317   void *const* FindGDM(void *K) const;
318 
319   template<typename T>
320   ProgramStateRef add(typename ProgramStateTrait<T>::key_type K) const;
321 
322   template <typename T>
323   typename ProgramStateTrait<T>::data_type
get()324   get() const {
325     return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex()));
326   }
327 
328   template<typename T>
329   typename ProgramStateTrait<T>::lookup_type
get(typename ProgramStateTrait<T>::key_type key)330   get(typename ProgramStateTrait<T>::key_type key) const {
331     void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
332     return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key);
333   }
334 
335   template <typename T>
336   typename ProgramStateTrait<T>::context_type get_context() const;
337 
338 
339   template<typename T>
340   ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K) const;
341 
342   template<typename T>
343   ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K,
344                         typename ProgramStateTrait<T>::context_type C) const;
345   template <typename T>
346   ProgramStateRef remove() const;
347 
348   template<typename T>
349   ProgramStateRef set(typename ProgramStateTrait<T>::data_type D) const;
350 
351   template<typename T>
352   ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
353                      typename ProgramStateTrait<T>::value_type E) const;
354 
355   template<typename T>
356   ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
357                      typename ProgramStateTrait<T>::value_type E,
358                      typename ProgramStateTrait<T>::context_type C) const;
359 
360   template<typename T>
contains(typename ProgramStateTrait<T>::key_type key)361   bool contains(typename ProgramStateTrait<T>::key_type key) const {
362     void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
363     return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key);
364   }
365 
366   // Pretty-printing.
367   void print(raw_ostream &Out, const char *nl = "\n",
368              const char *sep = "") const;
369   void printDOT(raw_ostream &Out) const;
370   void printTaint(raw_ostream &Out, const char *nl = "\n",
371                   const char *sep = "") const;
372 
373   void dump() const;
374   void dumpTaint() const;
375 
376 private:
377   friend void ProgramStateRetain(const ProgramState *state);
378   friend void ProgramStateRelease(const ProgramState *state);
379 
380   ProgramStateRef
381   invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
382                         const Expr *E, unsigned BlockCount,
383                         const LocationContext *LCtx,
384                         StoreManager::InvalidatedSymbols &IS,
385                         const CallOrObjCMessage *Call) const;
386 };
387 
388 //===----------------------------------------------------------------------===//
389 // ProgramStateManager - Factory object for ProgramStates.
390 //===----------------------------------------------------------------------===//
391 
392 class ProgramStateManager {
393   friend class ProgramState;
394   friend void ProgramStateRelease(const ProgramState *state);
395 private:
396   /// Eng - The SubEngine that owns this state manager.
397   SubEngine *Eng; /* Can be null. */
398 
399   EnvironmentManager                   EnvMgr;
400   OwningPtr<StoreManager>              StoreMgr;
401   OwningPtr<ConstraintManager>         ConstraintMgr;
402 
403   ProgramState::GenericDataMap::Factory     GDMFactory;
404 
405   typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
406   GDMContextsTy GDMContexts;
407 
408   /// StateSet - FoldingSet containing all the states created for analyzing
409   ///  a particular function.  This is used to unique states.
410   llvm::FoldingSet<ProgramState> StateSet;
411 
412   /// Object that manages the data for all created SVals.
413   OwningPtr<SValBuilder> svalBuilder;
414 
415   /// A BumpPtrAllocator to allocate states.
416   llvm::BumpPtrAllocator &Alloc;
417 
418   /// A vector of ProgramStates that we can reuse.
419   std::vector<ProgramState *> freeStates;
420 
421 public:
ProgramStateManager(ASTContext & Ctx,StoreManagerCreator CreateStoreManager,ConstraintManagerCreator CreateConstraintManager,llvm::BumpPtrAllocator & alloc,SubEngine & subeng)422   ProgramStateManager(ASTContext &Ctx,
423                  StoreManagerCreator CreateStoreManager,
424                  ConstraintManagerCreator CreateConstraintManager,
425                  llvm::BumpPtrAllocator& alloc,
426                  SubEngine &subeng)
427     : Eng(&subeng),
428       EnvMgr(alloc),
429       GDMFactory(alloc),
430       svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
431       Alloc(alloc) {
432     StoreMgr.reset((*CreateStoreManager)(*this));
433     ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng));
434   }
435 
ProgramStateManager(ASTContext & Ctx,StoreManagerCreator CreateStoreManager,ConstraintManager * ConstraintManagerPtr,llvm::BumpPtrAllocator & alloc)436   ProgramStateManager(ASTContext &Ctx,
437                  StoreManagerCreator CreateStoreManager,
438                  ConstraintManager* ConstraintManagerPtr,
439                  llvm::BumpPtrAllocator& alloc)
440     : Eng(0),
441       EnvMgr(alloc),
442       GDMFactory(alloc),
443       svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
444       Alloc(alloc) {
445     StoreMgr.reset((*CreateStoreManager)(*this));
446     ConstraintMgr.reset(ConstraintManagerPtr);
447   }
448 
449   ~ProgramStateManager();
450 
451   ProgramStateRef getInitialState(const LocationContext *InitLoc);
452 
getContext()453   ASTContext &getContext() { return svalBuilder->getContext(); }
getContext()454   const ASTContext &getContext() const { return svalBuilder->getContext(); }
455 
getBasicVals()456   BasicValueFactory &getBasicVals() {
457     return svalBuilder->getBasicValueFactory();
458   }
getBasicVals()459   const BasicValueFactory& getBasicVals() const {
460     return svalBuilder->getBasicValueFactory();
461   }
462 
getSValBuilder()463   SValBuilder &getSValBuilder() {
464     return *svalBuilder;
465   }
466 
getSymbolManager()467   SymbolManager &getSymbolManager() {
468     return svalBuilder->getSymbolManager();
469   }
getSymbolManager()470   const SymbolManager &getSymbolManager() const {
471     return svalBuilder->getSymbolManager();
472   }
473 
getAllocator()474   llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
475 
getRegionManager()476   MemRegionManager& getRegionManager() {
477     return svalBuilder->getRegionManager();
478   }
getRegionManager()479   const MemRegionManager& getRegionManager() const {
480     return svalBuilder->getRegionManager();
481   }
482 
getStoreManager()483   StoreManager& getStoreManager() { return *StoreMgr; }
getConstraintManager()484   ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
getOwningEngine()485   SubEngine* getOwningEngine() { return Eng; }
486 
487   ProgramStateRef removeDeadBindings(ProgramStateRef St,
488                                     const StackFrameContext *LCtx,
489                                     SymbolReaper& SymReaper);
490 
491   /// Marshal a new state for the callee in another translation unit.
492   /// 'state' is owned by the caller's engine.
493   ProgramStateRef MarshalState(ProgramStateRef state, const StackFrameContext *L);
494 
495 public:
496 
ArrayToPointer(Loc Array)497   SVal ArrayToPointer(Loc Array) {
498     return StoreMgr->ArrayToPointer(Array);
499   }
500 
501   // Methods that manipulate the GDM.
502   ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data);
503   ProgramStateRef removeGDM(ProgramStateRef state, void *Key);
504 
505   // Methods that query & manipulate the Store.
506 
iterBindings(ProgramStateRef state,StoreManager::BindingsHandler & F)507   void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) {
508     StoreMgr->iterBindings(state->getStore(), F);
509   }
510 
511   ProgramStateRef getPersistentState(ProgramState &Impl);
512   ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState,
513                                            ProgramStateRef GDMState);
514 
haveEqualEnvironments(ProgramStateRef S1,ProgramStateRef S2)515   bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) {
516     return S1->Env == S2->Env;
517   }
518 
haveEqualStores(ProgramStateRef S1,ProgramStateRef S2)519   bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) {
520     return S1->store == S2->store;
521   }
522 
523   //==---------------------------------------------------------------------==//
524   // Generic Data Map methods.
525   //==---------------------------------------------------------------------==//
526   //
527   // ProgramStateManager and ProgramState support a "generic data map" that allows
528   // different clients of ProgramState objects to embed arbitrary data within a
529   // ProgramState object.  The generic data map is essentially an immutable map
530   // from a "tag" (that acts as the "key" for a client) and opaque values.
531   // Tags/keys and values are simply void* values.  The typical way that clients
532   // generate unique tags are by taking the address of a static variable.
533   // Clients are responsible for ensuring that data values referred to by a
534   // the data pointer are immutable (and thus are essentially purely functional
535   // data).
536   //
537   // The templated methods below use the ProgramStateTrait<T> class
538   // to resolve keys into the GDM and to return data values to clients.
539   //
540 
541   // Trait based GDM dispatch.
542   template <typename T>
set(ProgramStateRef st,typename ProgramStateTrait<T>::data_type D)543   ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait<T>::data_type D) {
544     return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
545                   ProgramStateTrait<T>::MakeVoidPtr(D));
546   }
547 
548   template<typename T>
set(ProgramStateRef st,typename ProgramStateTrait<T>::key_type K,typename ProgramStateTrait<T>::value_type V,typename ProgramStateTrait<T>::context_type C)549   ProgramStateRef set(ProgramStateRef st,
550                      typename ProgramStateTrait<T>::key_type K,
551                      typename ProgramStateTrait<T>::value_type V,
552                      typename ProgramStateTrait<T>::context_type C) {
553 
554     return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
555      ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C)));
556   }
557 
558   template <typename T>
add(ProgramStateRef st,typename ProgramStateTrait<T>::key_type K,typename ProgramStateTrait<T>::context_type C)559   ProgramStateRef add(ProgramStateRef st,
560                      typename ProgramStateTrait<T>::key_type K,
561                      typename ProgramStateTrait<T>::context_type C) {
562     return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
563         ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C)));
564   }
565 
566   template <typename T>
remove(ProgramStateRef st,typename ProgramStateTrait<T>::key_type K,typename ProgramStateTrait<T>::context_type C)567   ProgramStateRef remove(ProgramStateRef st,
568                         typename ProgramStateTrait<T>::key_type K,
569                         typename ProgramStateTrait<T>::context_type C) {
570 
571     return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
572      ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C)));
573   }
574 
575   template <typename T>
remove(ProgramStateRef st)576   ProgramStateRef remove(ProgramStateRef st) {
577     return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
578   }
579 
580   void *FindGDMContext(void *index,
581                        void *(*CreateContext)(llvm::BumpPtrAllocator&),
582                        void  (*DeleteContext)(void*));
583 
584   template <typename T>
get_context()585   typename ProgramStateTrait<T>::context_type get_context() {
586     void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(),
587                              ProgramStateTrait<T>::CreateContext,
588                              ProgramStateTrait<T>::DeleteContext);
589 
590     return ProgramStateTrait<T>::MakeContext(p);
591   }
592 
getSymVal(ProgramStateRef St,SymbolRef sym)593   const llvm::APSInt* getSymVal(ProgramStateRef St, SymbolRef sym) {
594     return ConstraintMgr->getSymVal(St, sym);
595   }
596 
EndPath(ProgramStateRef St)597   void EndPath(ProgramStateRef St) {
598     ConstraintMgr->EndPath(St);
599   }
600 };
601 
602 
603 //===----------------------------------------------------------------------===//
604 // Out-of-line method definitions for ProgramState.
605 //===----------------------------------------------------------------------===//
606 
getRegion(const VarDecl * D,const LocationContext * LC)607 inline const VarRegion* ProgramState::getRegion(const VarDecl *D,
608                                                 const LocationContext *LC) const
609 {
610   return getStateManager().getRegionManager().getVarRegion(D, LC);
611 }
612 
assume(DefinedOrUnknownSVal Cond,bool Assumption)613 inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
614                                       bool Assumption) const {
615   if (Cond.isUnknown())
616     return this;
617 
618   return getStateManager().ConstraintMgr->assume(this, cast<DefinedSVal>(Cond),
619                                                  Assumption);
620 }
621 
622 inline std::pair<ProgramStateRef , ProgramStateRef >
assume(DefinedOrUnknownSVal Cond)623 ProgramState::assume(DefinedOrUnknownSVal Cond) const {
624   if (Cond.isUnknown())
625     return std::make_pair(this, this);
626 
627   return getStateManager().ConstraintMgr->assumeDual(this,
628                                                      cast<DefinedSVal>(Cond));
629 }
630 
bindLoc(SVal LV,SVal V)631 inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
632   return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
633 }
634 
getLValue(const VarDecl * VD,const LocationContext * LC)635 inline Loc ProgramState::getLValue(const VarDecl *VD,
636                                const LocationContext *LC) const {
637   return getStateManager().StoreMgr->getLValueVar(VD, LC);
638 }
639 
getLValue(const CompoundLiteralExpr * literal,const LocationContext * LC)640 inline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal,
641                                const LocationContext *LC) const {
642   return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
643 }
644 
getLValue(const ObjCIvarDecl * D,SVal Base)645 inline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
646   return getStateManager().StoreMgr->getLValueIvar(D, Base);
647 }
648 
getLValue(const FieldDecl * D,SVal Base)649 inline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const {
650   return getStateManager().StoreMgr->getLValueField(D, Base);
651 }
652 
getLValue(QualType ElementType,SVal Idx,SVal Base)653 inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
654   if (NonLoc *N = dyn_cast<NonLoc>(&Idx))
655     return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
656   return UnknownVal();
657 }
658 
getSymVal(SymbolRef sym)659 inline const llvm::APSInt *ProgramState::getSymVal(SymbolRef sym) const {
660   return getStateManager().getSymVal(this, sym);
661 }
662 
getSVal(const Stmt * Ex,const LocationContext * LCtx,bool useOnlyDirectBindings)663 inline SVal ProgramState::getSVal(const Stmt *Ex, const LocationContext *LCtx,
664                                   bool useOnlyDirectBindings) const{
665   return Env.getSVal(EnvironmentEntry(Ex, LCtx),
666                      *getStateManager().svalBuilder,
667                      useOnlyDirectBindings);
668 }
669 
670 inline SVal
getSValAsScalarOrLoc(const Stmt * S,const LocationContext * LCtx)671 ProgramState::getSValAsScalarOrLoc(const Stmt *S,
672                                    const LocationContext *LCtx) const {
673   if (const Expr *Ex = dyn_cast<Expr>(S)) {
674     QualType T = Ex->getType();
675     if (Ex->isLValue() || Loc::isLocType(T) || T->isIntegerType())
676       return getSVal(S, LCtx);
677   }
678 
679   return UnknownVal();
680 }
681 
getRawSVal(Loc LV,QualType T)682 inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
683   return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
684 }
685 
getSVal(const MemRegion * R)686 inline SVal ProgramState::getSVal(const MemRegion* R) const {
687   return getStateManager().StoreMgr->getBinding(getStore(),
688                                                 loc::MemRegionVal(R));
689 }
690 
getBasicVals()691 inline BasicValueFactory &ProgramState::getBasicVals() const {
692   return getStateManager().getBasicVals();
693 }
694 
getSymbolManager()695 inline SymbolManager &ProgramState::getSymbolManager() const {
696   return getStateManager().getSymbolManager();
697 }
698 
699 template<typename T>
add(typename ProgramStateTrait<T>::key_type K)700 ProgramStateRef ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
701   return getStateManager().add<T>(this, K, get_context<T>());
702 }
703 
704 template <typename T>
get_context()705 typename ProgramStateTrait<T>::context_type ProgramState::get_context() const {
706   return getStateManager().get_context<T>();
707 }
708 
709 template<typename T>
remove(typename ProgramStateTrait<T>::key_type K)710 ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
711   return getStateManager().remove<T>(this, K, get_context<T>());
712 }
713 
714 template<typename T>
remove(typename ProgramStateTrait<T>::key_type K,typename ProgramStateTrait<T>::context_type C)715 ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
716                                typename ProgramStateTrait<T>::context_type C) const {
717   return getStateManager().remove<T>(this, K, C);
718 }
719 
720 template <typename T>
remove()721 ProgramStateRef ProgramState::remove() const {
722   return getStateManager().remove<T>(this);
723 }
724 
725 template<typename T>
set(typename ProgramStateTrait<T>::data_type D)726 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
727   return getStateManager().set<T>(this, D);
728 }
729 
730 template<typename T>
set(typename ProgramStateTrait<T>::key_type K,typename ProgramStateTrait<T>::value_type E)731 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
732                             typename ProgramStateTrait<T>::value_type E) const {
733   return getStateManager().set<T>(this, K, E, get_context<T>());
734 }
735 
736 template<typename T>
set(typename ProgramStateTrait<T>::key_type K,typename ProgramStateTrait<T>::value_type E,typename ProgramStateTrait<T>::context_type C)737 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
738                             typename ProgramStateTrait<T>::value_type E,
739                             typename ProgramStateTrait<T>::context_type C) const {
740   return getStateManager().set<T>(this, K, E, C);
741 }
742 
743 template <typename CB>
scanReachableSymbols(SVal val)744 CB ProgramState::scanReachableSymbols(SVal val) const {
745   CB cb(this);
746   scanReachableSymbols(val, cb);
747   return cb;
748 }
749 
750 template <typename CB>
scanReachableSymbols(const SVal * beg,const SVal * end)751 CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
752   CB cb(this);
753   scanReachableSymbols(beg, end, cb);
754   return cb;
755 }
756 
757 template <typename CB>
scanReachableSymbols(const MemRegion * const * beg,const MemRegion * const * end)758 CB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
759                                  const MemRegion * const *end) const {
760   CB cb(this);
761   scanReachableSymbols(beg, end, cb);
762   return cb;
763 }
764 
765 /// \class ScanReachableSymbols
766 /// A Utility class that allows to visit the reachable symbols using a custom
767 /// SymbolVisitor.
768 class ScanReachableSymbols : public SubRegionMap::Visitor  {
769   virtual void anchor();
770   typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
771 
772   VisitedItems visited;
773   ProgramStateRef state;
774   SymbolVisitor &visitor;
775   OwningPtr<SubRegionMap> SRM;
776 public:
777 
ScanReachableSymbols(ProgramStateRef st,SymbolVisitor & v)778   ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v)
779     : state(st), visitor(v) {}
780 
781   bool scan(nonloc::CompoundVal val);
782   bool scan(SVal val);
783   bool scan(const MemRegion *R);
784   bool scan(const SymExpr *sym);
785 
786   // From SubRegionMap::Visitor.
Visit(const MemRegion * Parent,const MemRegion * SubRegion)787   bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
788     return scan(SubRegion);
789   }
790 };
791 
792 } // end GR namespace
793 
794 } // end clang namespace
795 
796 #endif
797