diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 49b5ac3ba19..0d973130401 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -650,35 +650,25 @@ protected: RegionBindingsRef B; -private: - GlobalsFilterKind GlobalsFilter; protected: const ClusterBindings *getCluster(const MemRegion *R) { return B.lookup(R); } - /// Returns true if the memory space of the given region is one of the global - /// regions specially included at the start of analysis. - bool isInitiallyIncludedGlobalRegion(const MemRegion *R) { - switch (GlobalsFilter) { - case GFK_None: - return false; - case GFK_SystemOnly: - return isa<GlobalSystemSpaceRegion>(R->getMemorySpace()); - case GFK_All: - return isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()); - } - - llvm_unreachable("unknown globals filter"); + /// Returns true if all clusters in the given memspace should be initially + /// included in the cluster analysis. Subclasses may provide their + /// own implementation. + bool includeEntireMemorySpace(const MemRegion *Base) { + return false; } public: ClusterAnalysis(RegionStoreManager &rm, ProgramStateManager &StateMgr, - RegionBindingsRef b, GlobalsFilterKind GFK) + RegionBindingsRef b ) : RM(rm), Ctx(StateMgr.getContext()), svalBuilder(StateMgr.getSValBuilder()), - B(b), GlobalsFilter(GFK) {} + B(b) {} RegionBindingsRef getRegionBindings() const { return B; } @@ -696,8 +686,9 @@ public: assert(!Cluster.isEmpty() && "Empty clusters should be removed"); static_cast<DERIVED*>(this)->VisitAddedToCluster(Base, Cluster); - // If this is an interesting global region, add it the work list up front. - if (isInitiallyIncludedGlobalRegion(Base)) + // If the base's memspace should be entirely invalidated, add the cluster + // to the workspace up front. + if (static_cast<DERIVED*>(this)->includeEntireMemorySpace(Base)) AddToWorkList(WorkListElement(Base), &Cluster); } } @@ -940,6 +931,7 @@ class invalidateRegionsWorker : public ClusterAnalysis<invalidateRegionsWorker> InvalidatedSymbols &IS; RegionAndSymbolInvalidationTraits &ITraits; StoreManager::InvalidatedRegions *Regions; + GlobalsFilterKind GlobalsFilter; public: invalidateRegionsWorker(RegionStoreManager &rm, ProgramStateManager &stateMgr, @@ -950,8 +942,9 @@ public: RegionAndSymbolInvalidationTraits &ITraitsIn, StoreManager::InvalidatedRegions *r, GlobalsFilterKind GFK) - : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, GFK), - Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r){} + : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b), + Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r), + GlobalsFilter(GFK) {} void VisitCluster(const MemRegion *baseR, const ClusterBindings *C); void VisitBinding(SVal V); @@ -959,6 +952,14 @@ public: using ClusterAnalysis::AddToWorkList; bool AddToWorkList(const MemRegion *R); + + /// Returns true if all clusters in the memory space for \p Base should be + /// be invalidated. + bool includeEntireMemorySpace(const MemRegion *Base); + + /// Returns true if the memory space of the given region is one of the global + /// regions specially included at the start of invalidation. + bool isInitiallyIncludedGlobalRegion(const MemRegion *R); }; } @@ -1159,6 +1160,29 @@ void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR, B = B.addBinding(baseR, BindingKey::Direct, V); } +bool invalidateRegionsWorker::isInitiallyIncludedGlobalRegion( + const MemRegion *R) { + switch (GlobalsFilter) { + case GFK_None: + return false; + case GFK_SystemOnly: + return isa<GlobalSystemSpaceRegion>(R->getMemorySpace()); + case GFK_All: + return isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()); + } + + llvm_unreachable("unknown globals filter"); +} + +bool invalidateRegionsWorker::includeEntireMemorySpace(const MemRegion *Base) { + if (isInitiallyIncludedGlobalRegion(Base)) + return true; + + const MemSpaceRegion *MemSpace = Base->getMemorySpace(); + return ITraits.hasTrait(MemSpace, + RegionAndSymbolInvalidationTraits::TK_EntireMemSpace); +} + RegionBindingsRef RegionStoreManager::invalidateGlobalRegion(MemRegion::Kind K, const Expr *Ex, @@ -2253,7 +2277,7 @@ public: ProgramStateManager &stateMgr, RegionBindingsRef b, SymbolReaper &symReaper, const StackFrameContext *LCtx) - : ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b, GFK_None), + : ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b), SymReaper(symReaper), CurrentLCtx(LCtx) {} // Called by ClusterAnalysis. |