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