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