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