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