From: Ted Kremenek Date: Tue, 3 Mar 2009 01:35:36 +0000 (+0000) Subject: Add StoreManager::getSubRegionMap(). This method returns an opaque mapping for clien... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=59e8f1128019aef95f45c6fa09cc0f8bfea99f13;p=clang Add StoreManager::getSubRegionMap(). This method returns an opaque mapping for clients of StoreManagers from MemRegions to their subregions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65914 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index ed30a8bca5..2f7920ac6b 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -31,7 +31,8 @@ class GRStateManager; class Stmt; class Expr; class ObjCIvarDecl; - +class SubRegionMap; + class StoreManager { protected: /// MRMgr - Manages region objects associated with this StoreManager. @@ -71,8 +72,17 @@ public: const CompoundLiteralExpr* CL, SVal V) = 0; + /// getInitialStore - Returns the initial "empty" store representing the + /// value bindings upon entry to an analyzed function. virtual Store getInitialStore() = 0; + + /// getRegionManager - Returns the internal RegionManager object that is + /// used to query and manipulate MemRegion objects. MemRegionManager& getRegionManager() { return MRMgr; } + + /// getSubRegionMap - Returns an opaque map object that clients can query + /// to get the subregions of a given MemRegion object. + virtual std::auto_ptr getSubRegionMap(const GRState *state) = 0; virtual SVal getLValueVar(const GRState* St, const VarDecl* VD) = 0; @@ -151,6 +161,21 @@ public: /// iterBindings - Iterate over the bindings in the Store. virtual void iterBindings(Store store, BindingsHandler& f) = 0; }; + +/// SubRegionMap - An abstract interface that represents a queryable map +/// between MemRegion objects and their subregions. +class SubRegionMap { +public: + virtual ~SubRegionMap() {} + + class Visitor { + public: + virtual ~Visitor() {} + virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion); + }; + + virtual void iterSubRegions(const MemRegion* R, Visitor& V) const = 0; +}; StoreManager* CreateBasicStoreManager(GRStateManager& StMgr); StoreManager* CreateRegionStoreManager(GRStateManager& StMgr); diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 85d96c4780..31408c0244 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -23,6 +23,15 @@ typedef llvm::ImmutableMap VarBindingsTy; namespace { +class VISIBILITY_HIDDEN BasicStoreSubRegionMap : public SubRegionMap { +public: + BasicStoreSubRegionMap() {} + + void iterSubRegions(const MemRegion* R, Visitor& V) const { + // Do nothing. No subregions. + } +}; + class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager { VarBindingsTy::Factory VBFactory; GRStateManager& StateMgr; @@ -37,6 +46,10 @@ public: ~BasicStoreManager() {} + std::auto_ptr getSubRegionMap(const GRState *state) { + return std::auto_ptr(new BasicStoreSubRegionMap()); + } + SVal Retrieve(const GRState *state, Loc loc, QualType T = QualType()); const GRState* Bind(const GRState* St, Loc L, SVal V) { diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index a76a870eb4..0671a806d2 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -105,6 +105,37 @@ namespace clang { namespace { +class VISIBILITY_HIDDEN RegionStoreSubRegionMap : public SubRegionMap { + typedef llvm::DenseMap > Map; + + llvm::ImmutableSet::Factory F; + Map M; + +public: + void add(const MemRegion* Parent, const MemRegion* SubRegion) { + Map::iterator I = M.find(Parent); + M.insert(std::make_pair(Parent, + F.Add(I == M.end() ? F.GetEmptySet() : I->second, SubRegion))); + } + + ~RegionStoreSubRegionMap() {} + + void iterSubRegions(const MemRegion* Parent, Visitor& V) const { + Map::iterator I = M.find(Parent); + + if (I == M.end()) + return; + + llvm::ImmutableSet S = I->second; + for (llvm::ImmutableSet::iterator SI=S.begin(),SE=S.end(); + SI != SE; ++SI) { + if (!V.Visit(Parent, *SI)) + return; + } + } +}; + class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager { RegionBindingsTy::Factory RBFactory; RegionViews::Factory RVFactory; @@ -128,6 +159,8 @@ public: MemRegionManager& getRegionManager() { return MRMgr; } + std::auto_ptr getSubRegionMap(const GRState *state); + const GRState* BindCompoundLiteral(const GRState* St, const CompoundLiteralExpr* CL, SVal V); @@ -268,6 +301,18 @@ StoreManager* clang::CreateRegionStoreManager(GRStateManager& StMgr) { return new RegionStoreManager(StMgr); } +std::auto_ptr +RegionStoreManager::getSubRegionMap(const GRState *state) { + RegionBindingsTy B = GetRegionBindings(state->getStore()); + RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap(); + + for (RegionBindingsTy::iterator I=B.begin(), E=B.end(); I!=E; ++I) { + if (const SubRegion* R = dyn_cast(I.getKey())) + M->add(R->getSuperRegion(), R); + } + + return std::auto_ptr(M); +} /// getLValueString - Returns an SVal representing the lvalue of a /// StringLiteral. Within RegionStore a StringLiteral has an