diff options
author | dim <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
commit | 554bcb69c2d785a011a30e7db87a36a87fe7db10 (patch) | |
tree | 9abb1a658a297776086f4e0dfa6ca533de02104e /include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h | |
parent | bb67ca86b31f67faee50bd10c3b036d65751745a (diff) | |
download | FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.zip FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.tar.gz |
Vendor import of clang trunk r161861:
http://llvm.org/svn/llvm-project/cfe/trunk@161861
Diffstat (limited to 'include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h')
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index 360d648..d36aa1b 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -35,7 +35,8 @@ class ASTContext; namespace ento { -class CallOrObjCMessage; +class CallEvent; +class CallEventManager; typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&, SubEngine&); @@ -49,13 +50,34 @@ template <typename T> struct ProgramStatePartialTrait; template <typename T> struct ProgramStateTrait { typedef typename T::data_type data_type; - static inline void *GDMIndex() { return &T::TagInt; } static inline void *MakeVoidPtr(data_type D) { return (void*) D; } static inline data_type MakeData(void *const* P) { return P ? (data_type) *P : (data_type) 0; } }; +/// \class Stores the dynamic type information. +/// Information about type of an object at runtime. This is used by dynamic +/// dispatch implementation. +class DynamicTypeInfo { + QualType T; + bool CanBeASubClass; + +public: + DynamicTypeInfo() : T(QualType()) {} + DynamicTypeInfo(QualType WithType, bool CanBeSub = true): + T(WithType), CanBeASubClass(CanBeSub) {} + QualType getType() { return T; } + bool canBeASubClass() { return CanBeASubClass; } + void Profile(llvm::FoldingSetNodeID &ID) const { + T.Profile(ID); + ID.AddInteger((unsigned)CanBeASubClass); + } + bool operator==(const DynamicTypeInfo &X) const { + return T == X.T && CanBeASubClass == X.CanBeASubClass; + } +}; + /// \class ProgramState /// ProgramState - This class encapsulates: /// @@ -220,12 +242,12 @@ public: const Expr *E, unsigned BlockCount, const LocationContext *LCtx, StoreManager::InvalidatedSymbols *IS = 0, - const CallOrObjCMessage *Call = 0) const; + const CallEvent *Call = 0) const; /// enterStackFrame - Returns the state for entry to the given stack frame, /// preserving the current state. - ProgramStateRef enterStackFrame(const LocationContext *callerCtx, - const StackFrameContext *calleeCtx) const; + ProgramStateRef enterStackFrame(const CallEvent &Call, + const StackFrameContext *CalleeCtx) const; /// Get the lvalue for a variable reference. Loc getLValue(const VarDecl *D, const LocationContext *LC) const; @@ -239,6 +261,9 @@ public: /// Get the lvalue for a field reference. SVal getLValue(const FieldDecl *decl, SVal Base) const; + /// Get the lvalue for an indirect field reference. + SVal getLValue(const IndirectFieldDecl *decl, SVal Base) const; + /// Get the lvalue for an array index. SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const; @@ -310,6 +335,20 @@ public: bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const; bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const; + /// \brief Get dynamic type information for a region. + DynamicTypeInfo getDynamicTypeInfo(const MemRegion *Reg) const; + + /// \brief Set dynamic type information of the region; return the new state. + ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg, + DynamicTypeInfo NewTy) const; + + /// \brief Set dynamic type information of the region; return the new state. + ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg, + QualType NewTy, + bool CanBeSubClassed = true) const { + return setDynamicTypeInfo(Reg, DynamicTypeInfo(NewTy, CanBeSubClassed)); + } + //==---------------------------------------------------------------------==// // Accessing the Generic Data Map (GDM). //==---------------------------------------------------------------------==// @@ -382,7 +421,7 @@ private: const Expr *E, unsigned BlockCount, const LocationContext *LCtx, StoreManager::InvalidatedSymbols &IS, - const CallOrObjCMessage *Call) const; + const CallEvent *Call) const; }; //===----------------------------------------------------------------------===// @@ -412,6 +451,9 @@ private: /// Object that manages the data for all created SVals. OwningPtr<SValBuilder> svalBuilder; + /// Manages memory for created CallEvents. + OwningPtr<CallEventManager> CallEventMgr; + /// A BumpPtrAllocator to allocate states. llvm::BumpPtrAllocator &Alloc; @@ -423,28 +465,7 @@ public: StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator& alloc, - SubEngine &subeng) - : Eng(&subeng), - EnvMgr(alloc), - GDMFactory(alloc), - svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)), - Alloc(alloc) { - StoreMgr.reset((*CreateStoreManager)(*this)); - ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng)); - } - - ProgramStateManager(ASTContext &Ctx, - StoreManagerCreator CreateStoreManager, - ConstraintManager* ConstraintManagerPtr, - llvm::BumpPtrAllocator& alloc) - : Eng(0), - EnvMgr(alloc), - GDMFactory(alloc), - svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)), - Alloc(alloc) { - StoreMgr.reset((*CreateStoreManager)(*this)); - ConstraintMgr.reset(ConstraintManagerPtr); - } + SubEngine &subeng); ~ProgramStateManager(); @@ -480,6 +501,8 @@ public: return svalBuilder->getRegionManager(); } + CallEventManager &getCallEventManager() { return *CallEventMgr; } + StoreManager& getStoreManager() { return *StoreMgr; } ConstraintManager& getConstraintManager() { return *ConstraintMgr; } SubEngine* getOwningEngine() { return Eng; } @@ -650,6 +673,18 @@ inline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const { return getStateManager().StoreMgr->getLValueField(D, Base); } +inline SVal ProgramState::getLValue(const IndirectFieldDecl *D, + SVal Base) const { + StoreManager &SM = *getStateManager().StoreMgr; + for (IndirectFieldDecl::chain_iterator I = D->chain_begin(), + E = D->chain_end(); + I != E; ++I) { + Base = SM.getLValueField(cast<FieldDecl>(*I), Base); + } + + return Base; +} + inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{ if (NonLoc *N = dyn_cast<NonLoc>(&Idx)) return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base); @@ -672,7 +707,7 @@ ProgramState::getSValAsScalarOrLoc(const Stmt *S, const LocationContext *LCtx) const { if (const Expr *Ex = dyn_cast<Expr>(S)) { QualType T = Ex->getType(); - if (Ex->isLValue() || Loc::isLocType(T) || T->isIntegerType()) + if (Ex->isGLValue() || Loc::isLocType(T) || T->isIntegerType()) return getSVal(S, LCtx); } @@ -765,14 +800,12 @@ CB ProgramState::scanReachableSymbols(const MemRegion * const *beg, /// \class ScanReachableSymbols /// A Utility class that allows to visit the reachable symbols using a custom /// SymbolVisitor. -class ScanReachableSymbols : public SubRegionMap::Visitor { - virtual void anchor(); +class ScanReachableSymbols { typedef llvm::DenseMap<const void*, unsigned> VisitedItems; VisitedItems visited; ProgramStateRef state; SymbolVisitor &visitor; - OwningPtr<SubRegionMap> SRM; public: ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v) @@ -782,11 +815,6 @@ public: bool scan(SVal val); bool scan(const MemRegion *R); bool scan(const SymExpr *sym); - - // From SubRegionMap::Visitor. - bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) { - return scan(SubRegion); - } }; } // end GR namespace |