From: Ted Kremenek Date: Mon, 25 Aug 2008 19:33:03 +0000 (+0000) Subject: Added 'extents' for Regions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0c4b28aa9e1a0754d71dc61c37cda94bc8d27ed;p=clang Added 'extents' for Regions. Added 'getExtent()' to StoreManager. Implemented 'getExtent()' for BasicStoreManager. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55321 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/BasicStore.h b/include/clang/Analysis/PathSensitive/BasicStore.h index 88ac9ce381..b936e2ac4f 100644 --- a/include/clang/Analysis/PathSensitive/BasicStore.h +++ b/include/clang/Analysis/PathSensitive/BasicStore.h @@ -18,10 +18,12 @@ namespace llvm { class llvm::BumpPtrAllocator; + class ASTContext; } namespace clang { - StoreManager* CreateBasicStoreManager(llvm::BumpPtrAllocator& Alloc); + StoreManager* CreateBasicStoreManager(llvm::BumpPtrAllocator& Alloc, + ASTContext& Ctx); } #endif diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index d5eb55ab6d..c360da9a7c 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -304,6 +304,7 @@ public: const GRState* getInitialState(); + ASTContext& getContext() { return BasicVals.getContext(); } BasicValueFactory& getBasicVals() { return BasicVals; } const BasicValueFactory& getBasicVals() const { return BasicVals; } SymbolManager& getSymbolManager() { return SymMgr; } diff --git a/include/clang/Analysis/PathSensitive/Regions.h b/include/clang/Analysis/PathSensitive/Regions.h index 9fd127c4a7..d62b033726 100644 --- a/include/clang/Analysis/PathSensitive/Regions.h +++ b/include/clang/Analysis/PathSensitive/Regions.h @@ -15,12 +15,94 @@ #include "llvm/Support/DataTypes.h" #include "llvm/Support/Casting.h" #include "llvm/ADT/FoldingSet.h" +#include "clang/Analysis/PathSensitive/SymbolManager.h" #ifndef LLVM_CLANG_ANALYSIS_REGIONS_H #define LLVM_CLANG_ANALYSIS_REGIONS_H +namespace llvm { + class APSInt; +} + namespace clang { +class BasicValueFactory; + + +//===----------------------------------------------------------------------===// +// Region Extents. +//===----------------------------------------------------------------------===// + +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; + } +}; + +//===----------------------------------------------------------------------===// +// Regions. +//===----------------------------------------------------------------------===// + class Region { public: enum Kind { Var = 0x0, Anon = 0x1 }; @@ -62,6 +144,8 @@ public: const VarDecl* getDecl() const { return (const VarDecl*) getData(); } operator const VarDecl*() const { return getDecl(); } + RegionExtent getExtent(BasicValueFactory& BV) const; + // Implement isa support. static inline bool classof(const Region* R) { return R->getKind() == Region::Var; diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index be824e774f..42ee328f60 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -52,6 +52,9 @@ public: virtual void print(Store store, std::ostream& Out, const char* nl, const char *sep) = 0; + + /// getExtent - Returns the size of the region in bits. + virtual RegionExtent getExtent(GRStateManager& SM, Region R) = 0; }; } // end clang namespace diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 2ed89c6f7d..c2482bcd3b 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -25,9 +25,12 @@ namespace { class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager { typedef llvm::ImmutableMap VarBindingsTy; VarBindingsTy::Factory VBFactory; + ASTContext& C; public: - BasicStoreManager(llvm::BumpPtrAllocator& A) : VBFactory(A) {} + BasicStoreManager(llvm::BumpPtrAllocator& A, ASTContext& c) + : VBFactory(A), C(c) {} + virtual ~BasicStoreManager() {} virtual RVal GetRVal(Store St, LVal LV, QualType T); @@ -51,13 +54,23 @@ public: virtual void print(Store store, std::ostream& Out, const char* nl, const char *sep); + + virtual RegionExtent getExtent(GRStateManager& SM, Region R); }; } // end anonymous namespace -StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A) { - return new BasicStoreManager(A); +StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A, + ASTContext& C) { + return new BasicStoreManager(A, C); +} + +RegionExtent BasicStoreManager::getExtent(GRStateManager& SM, Region R) { + if (VarRegion *VR = dyn_cast(&R)) + return VR->getExtent(SM.getBasicVals()); + + return UnknownExtent(); } RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) { @@ -75,30 +88,8 @@ RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) { return T ? *T : UnknownVal(); } - case lval::SymbolValKind: { - - // FIXME: This is a broken representation of memory, and is prone - // to crashing the analyzer when addresses to symbolic values are - // passed through casts. We need a better representation of symbolic - // memory (or just memory in general); probably we should do this - // as a plugin class (similar to GRTransferFuncs). - -#if 0 - const lval::SymbolVal& SV = cast(LV); - assert (T.getTypePtr()); - - // Punt on "symbolic" function pointers. - if (T->isFunctionType()) - return UnknownVal(); - - if (T->isPointerType()) - return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol())); - else - return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol())); -#endif - + case lval::SymbolValKind: return UnknownVal(); - } case lval::ConcreteIntKind: // Some clients may call GetRVal with such an option simply because diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 93ea5251e8..a14695d67e 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()), + StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator(), Ctx), G.getAllocator(), G.getCFG(), L), SymMgr(StateMgr.getSymbolManager()), CurrentStmt(NULL), diff --git a/lib/Analysis/Regions.cpp b/lib/Analysis/Regions.cpp new file mode 100644 index 0000000000..b725316243 --- /dev/null +++ b/lib/Analysis/Regions.cpp @@ -0,0 +1,34 @@ +//==- Regions.cpp - Abstract memory locations ----------------------*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines Region and its subclasses. Regions represent abstract +// memory locations. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/Regions.h" +#include "clang/Analysis/PathSensitive/BasicValueFactory.h" +#include "clang/AST/ASTContext.h" + +using namespace clang; + +RegionExtent VarRegion::getExtent(BasicValueFactory& BV) const { + QualType T = getDecl()->getType(); + + // FIXME: Add support for VLAs. This may require passing in additional + // information, or tracking a different region type. + if (!T.getTypePtr()->isConstantSizeType()) + return UnknownExtent(); + + ASTContext& C = BV.getContext(); + assert (!T->isObjCInterfaceType()); // @interface not a possible VarDecl type. + assert (T != C.VoidTy); // void not a possible VarDecl type. + return IntExtent(BV.getValue(C.getTypeSize(T), C.VoidPtrTy)); +} +