From 5f81c4415422b0aa5c59db69580b1079fc12a65f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 28 Aug 2008 23:31:31 +0000 Subject: [PATCH] Make store "Regions" and "Bindings" more abstract instead of concrete variants. Their precise semantics will be implemented by a specific StoreManager. Use function pointer to create the StoreManager in GRStateManager. This matches how we create ConstraintsManager. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55514 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../clang/Analysis/PathSensitive/BasicStore.h | 9 +-- .../clang/Analysis/PathSensitive/GRState.h | 17 +++-- include/clang/Analysis/PathSensitive/Store.h | 75 ++++++++++++++++++- lib/Analysis/BasicStore.cpp | 34 ++++++--- lib/Analysis/GRExprEngine.cpp | 2 +- 5 files changed, 108 insertions(+), 29 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/BasicStore.h b/include/clang/Analysis/PathSensitive/BasicStore.h index d9d3208ac5..0c7e8ece2a 100644 --- a/include/clang/Analysis/PathSensitive/BasicStore.h +++ b/include/clang/Analysis/PathSensitive/BasicStore.h @@ -16,14 +16,9 @@ #include "clang/Analysis/PathSensitive/Store.h" -namespace llvm { - class BumpPtrAllocator; - class ASTContext; -} - namespace clang { - StoreManager* CreateBasicStoreManager(llvm::BumpPtrAllocator& Alloc, - ASTContext& Ctx); + class GRStateManager; + StoreManager* CreateBasicStoreManager(GRStateManager& StMgr); } #endif diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index aca5a66a52..0ecfb27c16 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -288,15 +288,17 @@ private: const GRState* BindVar(const GRState* St, VarDecl* D, RVal V) { return SetRVal(St, lval::DeclVal(D), V); } - - typedef ConstraintManager* (*ConstraintManagerCreater)(GRStateManager&); -public: - GRStateManager(ASTContext& Ctx, StoreManager* stmgr, - ConstraintManagerCreater CreateConstraintManager, +public: + + typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&); + typedef StoreManager* (*StoreManagerCreator)(GRStateManager&); + + GRStateManager(ASTContext& Ctx, + StoreManagerCreator CreateStoreManager, + ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator& alloc, CFG& c, LiveVariables& L) : EnvMgr(alloc), - StMgr(stmgr), ISetFactory(alloc), GDMFactory(alloc), BasicVals(Ctx, alloc), @@ -304,7 +306,8 @@ public: Alloc(alloc), cfg(c), Liveness(L) { - ConstraintMgr.reset((*CreateConstraintManager)(*this)); + StMgr.reset((*CreateStoreManager)(*this)); + ConstraintMgr.reset((*CreateConstraintManager)(*this)); } ~GRStateManager(); diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 42ee328f60..0014c6dfb5 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -15,7 +15,6 @@ #define LLVM_CLANG_ANALYSIS_STORE_H #include "clang/Analysis/PathSensitive/RValues.h" -#include "clang/Analysis/PathSensitive/Regions.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/DenseSet.h" @@ -25,6 +24,78 @@ namespace clang { typedef const void* Store; + +namespace store { + typedef const void* Binding; + typedef const void* Region; + + class RegionExtent { + public: + enum Kind { Unknown = 0, Int = 0, Sym = 1 }; + + protected: + const uintptr_t Raw; + RegionExtent(uintptr_t raw, Kind k) : Raw(raw | k) {} + uintptr_t getData() const { return Raw & ~0x1; } + + public: + // Folding-set profiling. + void Profile(llvm::FoldingSetNodeID& ID) const { + ID.AddPointer((void*) Raw); + } + // Comparing extents. + bool operator==(const RegionExtent& R) const { + return Raw == R.Raw; + } + bool operator!=(const RegionExtent& R) const { + return Raw != R.Raw; + } + // Implement isa support. + Kind getKind() const { return Kind(Raw & 0x1); } + uintptr_t getRaw() const { return Raw; } + + static inline bool classof(const RegionExtent*) { + return true; + } + }; + + class UnknownExtent : public RegionExtent { + public: + UnknownExtent() : RegionExtent(0,Unknown) {} + + // Implement isa support. + static inline bool classof(const RegionExtent* E) { + return E->getRaw() == 0; + } + }; + + class IntExtent : public RegionExtent { + public: + IntExtent(const llvm::APSInt& X) : RegionExtent((uintptr_t) &X, Int) {} + + const llvm::APSInt& getInt() const { + return *((llvm::APSInt*) getData()); + } + + // Implement isa support. + static inline bool classof(const RegionExtent* E) { + return E->getKind() == Int && E->getRaw() != 0; + } + }; + + class SymExtent : public RegionExtent { + public: + SymExtent(SymbolID S) : RegionExtent(S.getNumber() << 1, Sym) {} + + SymbolID getSymbol() const { return SymbolID(getData() >> 1); } + + // Implement isa support. + static inline bool classof(const RegionExtent* E) { + return E->getKind() == Sym; + } + }; +} // end store namespace + class GRStateManager; class LiveVariables; class Stmt; @@ -54,7 +125,7 @@ public: const char* nl, const char *sep) = 0; /// getExtent - Returns the size of the region in bits. - virtual RegionExtent getExtent(GRStateManager& SM, Region R) = 0; + virtual store::RegionExtent getExtent(store::Region R) =0; }; } // end clang namespace diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index c2482bcd3b..f05a041179 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -11,25 +11,26 @@ // //===----------------------------------------------------------------------===// -#include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/PathSensitive/BasicStore.h" +#include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/PathSensitive/GRState.h" #include "llvm/ADT/ImmutableMap.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Streams.h" using namespace clang; +using store::Region; +using store::RegionExtent; namespace { class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager { typedef llvm::ImmutableMap VarBindingsTy; VarBindingsTy::Factory VBFactory; - ASTContext& C; + GRStateManager& StMgr; public: - BasicStoreManager(llvm::BumpPtrAllocator& A, ASTContext& c) - : VBFactory(A), C(c) {} + BasicStoreManager(GRStateManager& mgr) : StMgr(mgr) {} virtual ~BasicStoreManager() {} @@ -55,24 +56,33 @@ public: virtual void print(Store store, std::ostream& Out, const char* nl, const char *sep); - virtual RegionExtent getExtent(GRStateManager& SM, Region R); + virtual RegionExtent getExtent(Region R); }; } // end anonymous namespace -StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A, - ASTContext& C) { - return new BasicStoreManager(A, C); +StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) { + return new BasicStoreManager(StMgr); } -RegionExtent BasicStoreManager::getExtent(GRStateManager& SM, Region R) { - if (VarRegion *VR = dyn_cast(&R)) - return VR->getExtent(SM.getBasicVals()); +RegionExtent BasicStoreManager::getExtent(Region R) { + VarDecl* VD = (VarDecl*) R; + QualType T = VD->getType(); - return UnknownExtent(); + // FIXME: Add support for VLAs. This may require passing in additional + // information, or tracking a different region type. + if (!T.getTypePtr()->isConstantSizeType()) + return store::UnknownExtent(); + + ASTContext& C = StMgr.getContext(); + assert (!T->isObjCInterfaceType()); // @interface not a possible VarDecl type. + assert (T != C.VoidTy); // void not a possible VarDecl type. + return store::IntExtent(StMgr.getBasicVals().getValue(C.getTypeSize(T), + C.VoidPtrTy)); } + RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) { if (isa(LV)) diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index affb02a962..90ff435f86 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -120,7 +120,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, G(CoreEngine.getGraph()), Liveness(L), Builder(NULL), - StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator(), Ctx), + StateMgr(G.getContext(), CreateBasicStoreManager, CreateBasicConstraintManager, G.getAllocator(), G.getCFG(), L), SymMgr(StateMgr.getSymbolManager()), CurrentStmt(NULL), -- 2.40.0