clang API Documentation
00001 //== ProgramState.h - Path-sensitive "State" for tracking values -*- C++ -*--=// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the state of the program along the analysisa path. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H 00015 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H 00016 00017 #include "clang/Basic/LLVM.h" 00018 #include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h" 00019 #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h" 00020 #include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h" 00021 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" 00022 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" 00023 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 00024 #include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h" 00025 #include "llvm/ADT/FoldingSet.h" 00026 #include "llvm/ADT/ImmutableMap.h" 00027 #include "llvm/ADT/PointerIntPair.h" 00028 #include "llvm/Support/Allocator.h" 00029 00030 namespace llvm { 00031 class APSInt; 00032 } 00033 00034 namespace clang { 00035 class ASTContext; 00036 00037 namespace ento { 00038 00039 class CallEvent; 00040 class CallEventManager; 00041 00042 typedef std::unique_ptr<ConstraintManager>(*ConstraintManagerCreator)( 00043 ProgramStateManager &, SubEngine *); 00044 typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)( 00045 ProgramStateManager &); 00046 00047 //===----------------------------------------------------------------------===// 00048 // ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState. 00049 //===----------------------------------------------------------------------===// 00050 00051 template <typename T> struct ProgramStatePartialTrait; 00052 00053 template <typename T> struct ProgramStateTrait { 00054 typedef typename T::data_type data_type; 00055 static inline void *MakeVoidPtr(data_type D) { return (void*) D; } 00056 static inline data_type MakeData(void *const* P) { 00057 return P ? (data_type) *P : (data_type) 0; 00058 } 00059 }; 00060 00061 /// \class ProgramState 00062 /// ProgramState - This class encapsulates: 00063 /// 00064 /// 1. A mapping from expressions to values (Environment) 00065 /// 2. A mapping from locations to values (Store) 00066 /// 3. Constraints on symbolic values (GenericDataMap) 00067 /// 00068 /// Together these represent the "abstract state" of a program. 00069 /// 00070 /// ProgramState is intended to be used as a functional object; that is, 00071 /// once it is created and made "persistent" in a FoldingSet, its 00072 /// values will never change. 00073 class ProgramState : public llvm::FoldingSetNode { 00074 public: 00075 typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy; 00076 typedef llvm::ImmutableMap<void*, void*> GenericDataMap; 00077 00078 private: 00079 void operator=(const ProgramState& R) LLVM_DELETED_FUNCTION; 00080 00081 friend class ProgramStateManager; 00082 friend class ExplodedGraph; 00083 friend class ExplodedNode; 00084 00085 ProgramStateManager *stateMgr; 00086 Environment Env; // Maps a Stmt to its current SVal. 00087 Store store; // Maps a location to its current value. 00088 GenericDataMap GDM; // Custom data stored by a client of this class. 00089 unsigned refCount; 00090 00091 /// makeWithStore - Return a ProgramState with the same values as the current 00092 /// state with the exception of using the specified Store. 00093 ProgramStateRef makeWithStore(const StoreRef &store) const; 00094 00095 void setStore(const StoreRef &storeRef); 00096 00097 public: 00098 /// This ctor is used when creating the first ProgramState object. 00099 ProgramState(ProgramStateManager *mgr, const Environment& env, 00100 StoreRef st, GenericDataMap gdm); 00101 00102 /// Copy ctor - We must explicitly define this or else the "Next" ptr 00103 /// in FoldingSetNode will also get copied. 00104 ProgramState(const ProgramState &RHS); 00105 00106 ~ProgramState(); 00107 00108 /// Return the ProgramStateManager associated with this state. 00109 ProgramStateManager &getStateManager() const { 00110 return *stateMgr; 00111 } 00112 00113 /// Return the ConstraintManager. 00114 ConstraintManager &getConstraintManager() const; 00115 00116 /// getEnvironment - Return the environment associated with this state. 00117 /// The environment is the mapping from expressions to values. 00118 const Environment& getEnvironment() const { return Env; } 00119 00120 /// Return the store associated with this state. The store 00121 /// is a mapping from locations to values. 00122 Store getStore() const { return store; } 00123 00124 00125 /// getGDM - Return the generic data map associated with this state. 00126 GenericDataMap getGDM() const { return GDM; } 00127 00128 void setGDM(GenericDataMap gdm) { GDM = gdm; } 00129 00130 /// Profile - Profile the contents of a ProgramState object for use in a 00131 /// FoldingSet. Two ProgramState objects are considered equal if they 00132 /// have the same Environment, Store, and GenericDataMap. 00133 static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) { 00134 V->Env.Profile(ID); 00135 ID.AddPointer(V->store); 00136 V->GDM.Profile(ID); 00137 } 00138 00139 /// Profile - Used to profile the contents of this object for inclusion 00140 /// in a FoldingSet. 00141 void Profile(llvm::FoldingSetNodeID& ID) const { 00142 Profile(ID, this); 00143 } 00144 00145 BasicValueFactory &getBasicVals() const; 00146 SymbolManager &getSymbolManager() const; 00147 00148 //==---------------------------------------------------------------------==// 00149 // Constraints on values. 00150 //==---------------------------------------------------------------------==// 00151 // 00152 // Each ProgramState records constraints on symbolic values. These constraints 00153 // are managed using the ConstraintManager associated with a ProgramStateManager. 00154 // As constraints gradually accrue on symbolic values, added constraints 00155 // may conflict and indicate that a state is infeasible (as no real values 00156 // could satisfy all the constraints). This is the principal mechanism 00157 // for modeling path-sensitivity in ExprEngine/ProgramState. 00158 // 00159 // Various "assume" methods form the interface for adding constraints to 00160 // symbolic values. A call to 'assume' indicates an assumption being placed 00161 // on one or symbolic values. 'assume' methods take the following inputs: 00162 // 00163 // (1) A ProgramState object representing the current state. 00164 // 00165 // (2) The assumed constraint (which is specific to a given "assume" method). 00166 // 00167 // (3) A binary value "Assumption" that indicates whether the constraint is 00168 // assumed to be true or false. 00169 // 00170 // The output of "assume*" is a new ProgramState object with the added constraints. 00171 // If no new state is feasible, NULL is returned. 00172 // 00173 00174 /// Assumes that the value of \p cond is zero (if \p assumption is "false") 00175 /// or non-zero (if \p assumption is "true"). 00176 /// 00177 /// This returns a new state with the added constraint on \p cond. 00178 /// If no new state is feasible, NULL is returned. 00179 ProgramStateRef assume(DefinedOrUnknownSVal cond, bool assumption) const; 00180 00181 /// Assumes both "true" and "false" for \p cond, and returns both 00182 /// corresponding states (respectively). 00183 /// 00184 /// This is more efficient than calling assume() twice. Note that one (but not 00185 /// both) of the returned states may be NULL. 00186 std::pair<ProgramStateRef, ProgramStateRef> 00187 assume(DefinedOrUnknownSVal cond) const; 00188 00189 ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx, 00190 DefinedOrUnknownSVal upperBound, 00191 bool assumption, 00192 QualType IndexType = QualType()) const; 00193 00194 /// \brief Check if the given SVal is constrained to zero or is a zero 00195 /// constant. 00196 ConditionTruthVal isNull(SVal V) const; 00197 00198 /// Utility method for getting regions. 00199 const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const; 00200 00201 //==---------------------------------------------------------------------==// 00202 // Binding and retrieving values to/from the environment and symbolic store. 00203 //==---------------------------------------------------------------------==// 00204 00205 /// Create a new state by binding the value 'V' to the statement 'S' in the 00206 /// state's environment. 00207 ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx, 00208 SVal V, bool Invalidate = true) const; 00209 00210 ProgramStateRef bindLoc(Loc location, 00211 SVal V, 00212 bool notifyChanges = true) const; 00213 00214 ProgramStateRef bindLoc(SVal location, SVal V) const; 00215 00216 ProgramStateRef bindDefault(SVal loc, SVal V) const; 00217 00218 ProgramStateRef killBinding(Loc LV) const; 00219 00220 /// \brief Returns the state with bindings for the given regions 00221 /// cleared from the store. 00222 /// 00223 /// Optionally invalidates global regions as well. 00224 /// 00225 /// \param Regions the set of regions to be invalidated. 00226 /// \param E the expression that caused the invalidation. 00227 /// \param BlockCount The number of times the current basic block has been 00228 // visited. 00229 /// \param CausesPointerEscape the flag is set to true when 00230 /// the invalidation entails escape of a symbol (representing a 00231 /// pointer). For example, due to it being passed as an argument in a 00232 /// call. 00233 /// \param IS the set of invalidated symbols. 00234 /// \param Call if non-null, the invalidated regions represent parameters to 00235 /// the call and should be considered directly invalidated. 00236 /// \param ITraits information about special handling for a particular 00237 /// region/symbol. 00238 ProgramStateRef 00239 invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E, 00240 unsigned BlockCount, const LocationContext *LCtx, 00241 bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr, 00242 const CallEvent *Call = nullptr, 00243 RegionAndSymbolInvalidationTraits *ITraits = nullptr) const; 00244 00245 ProgramStateRef 00246 invalidateRegions(ArrayRef<SVal> Regions, const Expr *E, 00247 unsigned BlockCount, const LocationContext *LCtx, 00248 bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr, 00249 const CallEvent *Call = nullptr, 00250 RegionAndSymbolInvalidationTraits *ITraits = nullptr) const; 00251 00252 /// enterStackFrame - Returns the state for entry to the given stack frame, 00253 /// preserving the current state. 00254 ProgramStateRef enterStackFrame(const CallEvent &Call, 00255 const StackFrameContext *CalleeCtx) const; 00256 00257 /// Get the lvalue for a variable reference. 00258 Loc getLValue(const VarDecl *D, const LocationContext *LC) const; 00259 00260 Loc getLValue(const CompoundLiteralExpr *literal, 00261 const LocationContext *LC) const; 00262 00263 /// Get the lvalue for an ivar reference. 00264 SVal getLValue(const ObjCIvarDecl *decl, SVal base) const; 00265 00266 /// Get the lvalue for a field reference. 00267 SVal getLValue(const FieldDecl *decl, SVal Base) const; 00268 00269 /// Get the lvalue for an indirect field reference. 00270 SVal getLValue(const IndirectFieldDecl *decl, SVal Base) const; 00271 00272 /// Get the lvalue for an array index. 00273 SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const; 00274 00275 /// Returns the SVal bound to the statement 'S' in the state's environment. 00276 SVal getSVal(const Stmt *S, const LocationContext *LCtx) const; 00277 00278 SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const; 00279 00280 /// \brief Return the value bound to the specified location. 00281 /// Returns UnknownVal() if none found. 00282 SVal getSVal(Loc LV, QualType T = QualType()) const; 00283 00284 /// Returns the "raw" SVal bound to LV before any value simplfication. 00285 SVal getRawSVal(Loc LV, QualType T= QualType()) const; 00286 00287 /// \brief Return the value bound to the specified location. 00288 /// Returns UnknownVal() if none found. 00289 SVal getSVal(const MemRegion* R) const; 00290 00291 SVal getSValAsScalarOrLoc(const MemRegion *R) const; 00292 00293 /// \brief Visits the symbols reachable from the given SVal using the provided 00294 /// SymbolVisitor. 00295 /// 00296 /// This is a convenience API. Consider using ScanReachableSymbols class 00297 /// directly when making multiple scans on the same state with the same 00298 /// visitor to avoid repeated initialization cost. 00299 /// \sa ScanReachableSymbols 00300 bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const; 00301 00302 /// \brief Visits the symbols reachable from the SVals in the given range 00303 /// using the provided SymbolVisitor. 00304 bool scanReachableSymbols(const SVal *I, const SVal *E, 00305 SymbolVisitor &visitor) const; 00306 00307 /// \brief Visits the symbols reachable from the regions in the given 00308 /// MemRegions range using the provided SymbolVisitor. 00309 bool scanReachableSymbols(const MemRegion * const *I, 00310 const MemRegion * const *E, 00311 SymbolVisitor &visitor) const; 00312 00313 template <typename CB> CB scanReachableSymbols(SVal val) const; 00314 template <typename CB> CB scanReachableSymbols(const SVal *beg, 00315 const SVal *end) const; 00316 00317 template <typename CB> CB 00318 scanReachableSymbols(const MemRegion * const *beg, 00319 const MemRegion * const *end) const; 00320 00321 /// Create a new state in which the statement is marked as tainted. 00322 ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx, 00323 TaintTagType Kind = TaintTagGeneric) const; 00324 00325 /// Create a new state in which the symbol is marked as tainted. 00326 ProgramStateRef addTaint(SymbolRef S, 00327 TaintTagType Kind = TaintTagGeneric) const; 00328 00329 /// Create a new state in which the region symbol is marked as tainted. 00330 ProgramStateRef addTaint(const MemRegion *R, 00331 TaintTagType Kind = TaintTagGeneric) const; 00332 00333 /// Check if the statement is tainted in the current state. 00334 bool isTainted(const Stmt *S, const LocationContext *LCtx, 00335 TaintTagType Kind = TaintTagGeneric) const; 00336 bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const; 00337 bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const; 00338 bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const; 00339 00340 /// \brief Get dynamic type information for a region. 00341 DynamicTypeInfo getDynamicTypeInfo(const MemRegion *Reg) const; 00342 00343 /// \brief Set dynamic type information of the region; return the new state. 00344 ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg, 00345 DynamicTypeInfo NewTy) const; 00346 00347 /// \brief Set dynamic type information of the region; return the new state. 00348 ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg, 00349 QualType NewTy, 00350 bool CanBeSubClassed = true) const { 00351 return setDynamicTypeInfo(Reg, DynamicTypeInfo(NewTy, CanBeSubClassed)); 00352 } 00353 00354 //==---------------------------------------------------------------------==// 00355 // Accessing the Generic Data Map (GDM). 00356 //==---------------------------------------------------------------------==// 00357 00358 void *const* FindGDM(void *K) const; 00359 00360 template<typename T> 00361 ProgramStateRef add(typename ProgramStateTrait<T>::key_type K) const; 00362 00363 template <typename T> 00364 typename ProgramStateTrait<T>::data_type 00365 get() const { 00366 return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex())); 00367 } 00368 00369 template<typename T> 00370 typename ProgramStateTrait<T>::lookup_type 00371 get(typename ProgramStateTrait<T>::key_type key) const { 00372 void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex()); 00373 return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key); 00374 } 00375 00376 template <typename T> 00377 typename ProgramStateTrait<T>::context_type get_context() const; 00378 00379 00380 template<typename T> 00381 ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K) const; 00382 00383 template<typename T> 00384 ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K, 00385 typename ProgramStateTrait<T>::context_type C) const; 00386 template <typename T> 00387 ProgramStateRef remove() const; 00388 00389 template<typename T> 00390 ProgramStateRef set(typename ProgramStateTrait<T>::data_type D) const; 00391 00392 template<typename T> 00393 ProgramStateRef set(typename ProgramStateTrait<T>::key_type K, 00394 typename ProgramStateTrait<T>::value_type E) const; 00395 00396 template<typename T> 00397 ProgramStateRef set(typename ProgramStateTrait<T>::key_type K, 00398 typename ProgramStateTrait<T>::value_type E, 00399 typename ProgramStateTrait<T>::context_type C) const; 00400 00401 template<typename T> 00402 bool contains(typename ProgramStateTrait<T>::key_type key) const { 00403 void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex()); 00404 return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key); 00405 } 00406 00407 // Pretty-printing. 00408 void print(raw_ostream &Out, const char *nl = "\n", 00409 const char *sep = "") const; 00410 void printDOT(raw_ostream &Out) const; 00411 void printTaint(raw_ostream &Out, const char *nl = "\n", 00412 const char *sep = "") const; 00413 00414 void dump() const; 00415 void dumpTaint() const; 00416 00417 private: 00418 friend void ProgramStateRetain(const ProgramState *state); 00419 friend void ProgramStateRelease(const ProgramState *state); 00420 00421 /// \sa invalidateValues() 00422 /// \sa invalidateRegions() 00423 ProgramStateRef 00424 invalidateRegionsImpl(ArrayRef<SVal> Values, 00425 const Expr *E, unsigned BlockCount, 00426 const LocationContext *LCtx, 00427 bool ResultsInSymbolEscape, 00428 InvalidatedSymbols *IS, 00429 RegionAndSymbolInvalidationTraits *HTraits, 00430 const CallEvent *Call) const; 00431 }; 00432 00433 //===----------------------------------------------------------------------===// 00434 // ProgramStateManager - Factory object for ProgramStates. 00435 //===----------------------------------------------------------------------===// 00436 00437 class ProgramStateManager { 00438 friend class ProgramState; 00439 friend void ProgramStateRelease(const ProgramState *state); 00440 private: 00441 /// Eng - The SubEngine that owns this state manager. 00442 SubEngine *Eng; /* Can be null. */ 00443 00444 EnvironmentManager EnvMgr; 00445 std::unique_ptr<StoreManager> StoreMgr; 00446 std::unique_ptr<ConstraintManager> ConstraintMgr; 00447 00448 ProgramState::GenericDataMap::Factory GDMFactory; 00449 00450 typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy; 00451 GDMContextsTy GDMContexts; 00452 00453 /// StateSet - FoldingSet containing all the states created for analyzing 00454 /// a particular function. This is used to unique states. 00455 llvm::FoldingSet<ProgramState> StateSet; 00456 00457 /// Object that manages the data for all created SVals. 00458 std::unique_ptr<SValBuilder> svalBuilder; 00459 00460 /// Manages memory for created CallEvents. 00461 std::unique_ptr<CallEventManager> CallEventMgr; 00462 00463 /// A BumpPtrAllocator to allocate states. 00464 llvm::BumpPtrAllocator &Alloc; 00465 00466 /// A vector of ProgramStates that we can reuse. 00467 std::vector<ProgramState *> freeStates; 00468 00469 public: 00470 ProgramStateManager(ASTContext &Ctx, 00471 StoreManagerCreator CreateStoreManager, 00472 ConstraintManagerCreator CreateConstraintManager, 00473 llvm::BumpPtrAllocator& alloc, 00474 SubEngine *subeng); 00475 00476 ~ProgramStateManager(); 00477 00478 ProgramStateRef getInitialState(const LocationContext *InitLoc); 00479 00480 ASTContext &getContext() { return svalBuilder->getContext(); } 00481 const ASTContext &getContext() const { return svalBuilder->getContext(); } 00482 00483 BasicValueFactory &getBasicVals() { 00484 return svalBuilder->getBasicValueFactory(); 00485 } 00486 00487 SValBuilder &getSValBuilder() { 00488 return *svalBuilder; 00489 } 00490 00491 SymbolManager &getSymbolManager() { 00492 return svalBuilder->getSymbolManager(); 00493 } 00494 const SymbolManager &getSymbolManager() const { 00495 return svalBuilder->getSymbolManager(); 00496 } 00497 00498 llvm::BumpPtrAllocator& getAllocator() { return Alloc; } 00499 00500 MemRegionManager& getRegionManager() { 00501 return svalBuilder->getRegionManager(); 00502 } 00503 const MemRegionManager& getRegionManager() const { 00504 return svalBuilder->getRegionManager(); 00505 } 00506 00507 CallEventManager &getCallEventManager() { return *CallEventMgr; } 00508 00509 StoreManager& getStoreManager() { return *StoreMgr; } 00510 ConstraintManager& getConstraintManager() { return *ConstraintMgr; } 00511 SubEngine* getOwningEngine() { return Eng; } 00512 00513 ProgramStateRef removeDeadBindings(ProgramStateRef St, 00514 const StackFrameContext *LCtx, 00515 SymbolReaper& SymReaper); 00516 00517 public: 00518 00519 SVal ArrayToPointer(Loc Array, QualType ElementTy) { 00520 return StoreMgr->ArrayToPointer(Array, ElementTy); 00521 } 00522 00523 // Methods that manipulate the GDM. 00524 ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data); 00525 ProgramStateRef removeGDM(ProgramStateRef state, void *Key); 00526 00527 // Methods that query & manipulate the Store. 00528 00529 void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) { 00530 StoreMgr->iterBindings(state->getStore(), F); 00531 } 00532 00533 ProgramStateRef getPersistentState(ProgramState &Impl); 00534 ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, 00535 ProgramStateRef GDMState); 00536 00537 bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) { 00538 return S1->Env == S2->Env; 00539 } 00540 00541 bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) { 00542 return S1->store == S2->store; 00543 } 00544 00545 //==---------------------------------------------------------------------==// 00546 // Generic Data Map methods. 00547 //==---------------------------------------------------------------------==// 00548 // 00549 // ProgramStateManager and ProgramState support a "generic data map" that allows 00550 // different clients of ProgramState objects to embed arbitrary data within a 00551 // ProgramState object. The generic data map is essentially an immutable map 00552 // from a "tag" (that acts as the "key" for a client) and opaque values. 00553 // Tags/keys and values are simply void* values. The typical way that clients 00554 // generate unique tags are by taking the address of a static variable. 00555 // Clients are responsible for ensuring that data values referred to by a 00556 // the data pointer are immutable (and thus are essentially purely functional 00557 // data). 00558 // 00559 // The templated methods below use the ProgramStateTrait<T> class 00560 // to resolve keys into the GDM and to return data values to clients. 00561 // 00562 00563 // Trait based GDM dispatch. 00564 template <typename T> 00565 ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait<T>::data_type D) { 00566 return addGDM(st, ProgramStateTrait<T>::GDMIndex(), 00567 ProgramStateTrait<T>::MakeVoidPtr(D)); 00568 } 00569 00570 template<typename T> 00571 ProgramStateRef set(ProgramStateRef st, 00572 typename ProgramStateTrait<T>::key_type K, 00573 typename ProgramStateTrait<T>::value_type V, 00574 typename ProgramStateTrait<T>::context_type C) { 00575 00576 return addGDM(st, ProgramStateTrait<T>::GDMIndex(), 00577 ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C))); 00578 } 00579 00580 template <typename T> 00581 ProgramStateRef add(ProgramStateRef st, 00582 typename ProgramStateTrait<T>::key_type K, 00583 typename ProgramStateTrait<T>::context_type C) { 00584 return addGDM(st, ProgramStateTrait<T>::GDMIndex(), 00585 ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C))); 00586 } 00587 00588 template <typename T> 00589 ProgramStateRef remove(ProgramStateRef st, 00590 typename ProgramStateTrait<T>::key_type K, 00591 typename ProgramStateTrait<T>::context_type C) { 00592 00593 return addGDM(st, ProgramStateTrait<T>::GDMIndex(), 00594 ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C))); 00595 } 00596 00597 template <typename T> 00598 ProgramStateRef remove(ProgramStateRef st) { 00599 return removeGDM(st, ProgramStateTrait<T>::GDMIndex()); 00600 } 00601 00602 void *FindGDMContext(void *index, 00603 void *(*CreateContext)(llvm::BumpPtrAllocator&), 00604 void (*DeleteContext)(void*)); 00605 00606 template <typename T> 00607 typename ProgramStateTrait<T>::context_type get_context() { 00608 void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(), 00609 ProgramStateTrait<T>::CreateContext, 00610 ProgramStateTrait<T>::DeleteContext); 00611 00612 return ProgramStateTrait<T>::MakeContext(p); 00613 } 00614 00615 void EndPath(ProgramStateRef St) { 00616 ConstraintMgr->EndPath(St); 00617 } 00618 }; 00619 00620 00621 //===----------------------------------------------------------------------===// 00622 // Out-of-line method definitions for ProgramState. 00623 //===----------------------------------------------------------------------===// 00624 00625 inline ConstraintManager &ProgramState::getConstraintManager() const { 00626 return stateMgr->getConstraintManager(); 00627 } 00628 00629 inline const VarRegion* ProgramState::getRegion(const VarDecl *D, 00630 const LocationContext *LC) const 00631 { 00632 return getStateManager().getRegionManager().getVarRegion(D, LC); 00633 } 00634 00635 inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond, 00636 bool Assumption) const { 00637 if (Cond.isUnknown()) 00638 return this; 00639 00640 return getStateManager().ConstraintMgr 00641 ->assume(this, Cond.castAs<DefinedSVal>(), Assumption); 00642 } 00643 00644 inline std::pair<ProgramStateRef , ProgramStateRef > 00645 ProgramState::assume(DefinedOrUnknownSVal Cond) const { 00646 if (Cond.isUnknown()) 00647 return std::make_pair(this, this); 00648 00649 return getStateManager().ConstraintMgr 00650 ->assumeDual(this, Cond.castAs<DefinedSVal>()); 00651 } 00652 00653 inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const { 00654 if (Optional<Loc> L = LV.getAs<Loc>()) 00655 return bindLoc(*L, V); 00656 return this; 00657 } 00658 00659 inline Loc ProgramState::getLValue(const VarDecl *VD, 00660 const LocationContext *LC) const { 00661 return getStateManager().StoreMgr->getLValueVar(VD, LC); 00662 } 00663 00664 inline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal, 00665 const LocationContext *LC) const { 00666 return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC); 00667 } 00668 00669 inline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const { 00670 return getStateManager().StoreMgr->getLValueIvar(D, Base); 00671 } 00672 00673 inline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const { 00674 return getStateManager().StoreMgr->getLValueField(D, Base); 00675 } 00676 00677 inline SVal ProgramState::getLValue(const IndirectFieldDecl *D, 00678 SVal Base) const { 00679 StoreManager &SM = *getStateManager().StoreMgr; 00680 for (const auto *I : D->chain()) { 00681 Base = SM.getLValueField(cast<FieldDecl>(I), Base); 00682 } 00683 00684 return Base; 00685 } 00686 00687 inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{ 00688 if (Optional<NonLoc> N = Idx.getAs<NonLoc>()) 00689 return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base); 00690 return UnknownVal(); 00691 } 00692 00693 inline SVal ProgramState::getSVal(const Stmt *Ex, 00694 const LocationContext *LCtx) const{ 00695 return Env.getSVal(EnvironmentEntry(Ex, LCtx), 00696 *getStateManager().svalBuilder); 00697 } 00698 00699 inline SVal 00700 ProgramState::getSValAsScalarOrLoc(const Stmt *S, 00701 const LocationContext *LCtx) const { 00702 if (const Expr *Ex = dyn_cast<Expr>(S)) { 00703 QualType T = Ex->getType(); 00704 if (Ex->isGLValue() || Loc::isLocType(T) || 00705 T->isIntegralOrEnumerationType()) 00706 return getSVal(S, LCtx); 00707 } 00708 00709 return UnknownVal(); 00710 } 00711 00712 inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const { 00713 return getStateManager().StoreMgr->getBinding(getStore(), LV, T); 00714 } 00715 00716 inline SVal ProgramState::getSVal(const MemRegion* R) const { 00717 return getStateManager().StoreMgr->getBinding(getStore(), 00718 loc::MemRegionVal(R)); 00719 } 00720 00721 inline BasicValueFactory &ProgramState::getBasicVals() const { 00722 return getStateManager().getBasicVals(); 00723 } 00724 00725 inline SymbolManager &ProgramState::getSymbolManager() const { 00726 return getStateManager().getSymbolManager(); 00727 } 00728 00729 template<typename T> 00730 ProgramStateRef ProgramState::add(typename ProgramStateTrait<T>::key_type K) const { 00731 return getStateManager().add<T>(this, K, get_context<T>()); 00732 } 00733 00734 template <typename T> 00735 typename ProgramStateTrait<T>::context_type ProgramState::get_context() const { 00736 return getStateManager().get_context<T>(); 00737 } 00738 00739 template<typename T> 00740 ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const { 00741 return getStateManager().remove<T>(this, K, get_context<T>()); 00742 } 00743 00744 template<typename T> 00745 ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K, 00746 typename ProgramStateTrait<T>::context_type C) const { 00747 return getStateManager().remove<T>(this, K, C); 00748 } 00749 00750 template <typename T> 00751 ProgramStateRef ProgramState::remove() const { 00752 return getStateManager().remove<T>(this); 00753 } 00754 00755 template<typename T> 00756 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::data_type D) const { 00757 return getStateManager().set<T>(this, D); 00758 } 00759 00760 template<typename T> 00761 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K, 00762 typename ProgramStateTrait<T>::value_type E) const { 00763 return getStateManager().set<T>(this, K, E, get_context<T>()); 00764 } 00765 00766 template<typename T> 00767 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K, 00768 typename ProgramStateTrait<T>::value_type E, 00769 typename ProgramStateTrait<T>::context_type C) const { 00770 return getStateManager().set<T>(this, K, E, C); 00771 } 00772 00773 template <typename CB> 00774 CB ProgramState::scanReachableSymbols(SVal val) const { 00775 CB cb(this); 00776 scanReachableSymbols(val, cb); 00777 return cb; 00778 } 00779 00780 template <typename CB> 00781 CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const { 00782 CB cb(this); 00783 scanReachableSymbols(beg, end, cb); 00784 return cb; 00785 } 00786 00787 template <typename CB> 00788 CB ProgramState::scanReachableSymbols(const MemRegion * const *beg, 00789 const MemRegion * const *end) const { 00790 CB cb(this); 00791 scanReachableSymbols(beg, end, cb); 00792 return cb; 00793 } 00794 00795 /// \class ScanReachableSymbols 00796 /// A Utility class that allows to visit the reachable symbols using a custom 00797 /// SymbolVisitor. 00798 class ScanReachableSymbols { 00799 typedef llvm::DenseSet<const void*> VisitedItems; 00800 00801 VisitedItems visited; 00802 ProgramStateRef state; 00803 SymbolVisitor &visitor; 00804 public: 00805 00806 ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v) 00807 : state(st), visitor(v) {} 00808 00809 bool scan(nonloc::LazyCompoundVal val); 00810 bool scan(nonloc::CompoundVal val); 00811 bool scan(SVal val); 00812 bool scan(const MemRegion *R); 00813 bool scan(const SymExpr *sym); 00814 }; 00815 00816 } // end ento namespace 00817 00818 } // end clang namespace 00819 00820 #endif