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