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; 51 static inline void* GDMIndex() { return &T::TagInt; } 52 static inline void* MakeVoidPtr(data_type D) { return (void*) D; } 53 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. 108 GRStateManager &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 GRState object for use in a 128 /// FoldingSet. Two GRState objects are considered equal if they 129 /// have the same Environment, Store, and GenericDataMap. 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. 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 304 get() const { 305 return GRStateTrait<T>::MakeData(FindGDM(GRStateTrait<T>::GDMIndex())); 306 } 307 308 template<typename T> 309 typename GRStateTrait<T>::lookup_type 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> 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: 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. 364 void incrementReferenceCount() { ++refCount; } 365 366 /// Decrement the number of times this state is referenced by ExplodeNodes. 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: 383 GRStateSet() {} 384 385 inline void Add(const GRState* St) { 386 Impl.insert(St); 387 } 388 389 typedef ImplTy::const_iterator iterator; 390 391 inline unsigned size() const { return Impl.size(); } 392 inline bool empty() const { return Impl.empty(); } 393 394 inline iterator begin() const { return Impl.begin(); } 395 inline iterator end() const { return Impl.end(); } 396 397 class AutoPopulate { 398 GRStateSet& S; 399 unsigned StartSize; 400 const GRState* St; 401 public: 402 AutoPopulate(GRStateSet& s, const GRState* st) 403 : S(s), StartSize(S.size()), St(st) {} 404 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: 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 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 485 ASTContext &getContext() { return svalBuilder->getContext(); } 486 const ASTContext &getContext() const { return svalBuilder->getContext(); } 487 488 BasicValueFactory &getBasicVals() { 489 return svalBuilder->getBasicValueFactory(); 490 } 491 const BasicValueFactory& getBasicVals() const { 492 return svalBuilder->getBasicValueFactory(); 493 } 494 495 SValBuilder &getSValBuilder() { 496 return *svalBuilder; 497 } 498 499 SymbolManager &getSymbolManager() { 500 return svalBuilder->getSymbolManager(); 501 } 502 const SymbolManager &getSymbolManager() const { 503 return svalBuilder->getSymbolManager(); 504 } 505 506 llvm::BumpPtrAllocator& getAllocator() { return Alloc; } 507 508 MemRegionManager& getRegionManager() { 509 return svalBuilder->getRegionManager(); 510 } 511 const MemRegionManager& getRegionManager() const { 512 return svalBuilder->getRegionManager(); 513 } 514 515 StoreManager& getStoreManager() { return *StoreMgr; } 516 ConstraintManager& getConstraintManager() { return *ConstraintMgr; } 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 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 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> 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> 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> 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> 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> 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> 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 619 const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) { 620 return ConstraintMgr->getSymVal(St, sym); 621 } 622 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 633 inline const VarRegion* GRState::getRegion(const VarDecl *D, 634 const LocationContext *LC) const { 635 return getStateManager().getRegionManager().getVarRegion(D, LC); 636 } 637 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*> 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 656 inline const GRState *GRState::bindLoc(SVal LV, SVal V) const { 657 return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V); 658 } 659 660 inline Loc GRState::getLValue(const VarDecl* VD, 661 const LocationContext *LC) const { 662 return getStateManager().StoreMgr->getLValueVar(VD, LC); 663 } 664 665 inline Loc GRState::getLValue(const StringLiteral *literal) const { 666 return getStateManager().StoreMgr->getLValueString(literal); 667 } 668 669 inline Loc GRState::getLValue(const CompoundLiteralExpr *literal, 670 const LocationContext *LC) const { 671 return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC); 672 } 673 674 inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const { 675 return getStateManager().StoreMgr->getLValueIvar(D, Base); 676 } 677 678 inline SVal GRState::getLValue(const FieldDecl* D, SVal Base) const { 679 return getStateManager().StoreMgr->getLValueField(D, Base); 680 } 681 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 688 inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const { 689 return getStateManager().getSymVal(this, sym); 690 } 691 692 inline SVal GRState::getSVal(const Stmt* Ex, bool useOnlyDirectBindings) const{ 693 return Env.getSVal(Ex, *getStateManager().svalBuilder, 694 useOnlyDirectBindings); 695 } 696 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 707 inline SVal GRState::getRawSVal(Loc LV, QualType T) const { 708 return getStateManager().StoreMgr->Retrieve(getStore(), LV, T); 709 } 710 711 inline SVal GRState::getSVal(const MemRegion* R) const { 712 return getStateManager().StoreMgr->Retrieve(getStore(), loc::MemRegionVal(R)); 713 } 714 715 inline BasicValueFactory &GRState::getBasicVals() const { 716 return getStateManager().getBasicVals(); 717 } 718 719 inline SymbolManager &GRState::getSymbolManager() const { 720 return getStateManager().getSymbolManager(); 721 } 722 723 template<typename T> 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> 729 typename GRStateTrait<T>::context_type GRState::get_context() const { 730 return getStateManager().get_context<T>(); 731 } 732 733 template<typename T> 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> 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> 745 const GRState *GRState::remove() const { 746 return getStateManager().remove<T>(this); 747 } 748 749 template<typename T> 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> 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> 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> 768 CB GRState::scanReachableSymbols(SVal val) const { 769 CB cb(this); 770 scanReachableSymbols(val, cb); 771 return cb; 772 } 773 774 template <typename CB> 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> 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