diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-08-06 00:29:57 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-08-06 00:29:57 +0000 |
commit | bea2753da897ede723e70bcd17023d050b0603d0 (patch) | |
tree | 1b3dedcc27352f2233932c2f5ffe4ed65cb5baed /lib | |
parent | 5a58c6d66db05ad17673e2258946b61898721cd7 (diff) |
[analyzer] Change SymbolReaper to store region roots implied by the Environment, allowing it be queried when
determining if symbols derived from regions are still live.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137005 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/StaticAnalyzer/Core/Environment.cpp | 7 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/GRState.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 15 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SymbolManager.cpp | 17 |
4 files changed, 24 insertions, 21 deletions
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp index b34a481e32..a695437f26 100644 --- a/lib/StaticAnalyzer/Core/Environment.cpp +++ b/lib/StaticAnalyzer/Core/Environment.cpp @@ -143,8 +143,7 @@ static inline bool IsLocation(const Stmt *S) { Environment EnvironmentManager::removeDeadBindings(Environment Env, SymbolReaper &SymReaper, - const GRState *ST, - SmallVectorImpl<const MemRegion*> &DRoots) { + const GRState *ST) { // We construct a new Environment object entirely, as this is cheaper than // individually removing all the subexpression bindings (which will greatly @@ -175,8 +174,8 @@ EnvironmentManager::removeDeadBindings(Environment Env, // If the block expr's value is a memory region, then mark that region. if (isa<loc::MemRegionVal>(X)) { - const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion(); - DRoots.push_back(R); + const MemRegion *R = cast<loc::MemRegionVal>(X).getRegion(); + SymReaper.markLive(R); } // Mark all symbols in the block expr's value live. diff --git a/lib/StaticAnalyzer/Core/GRState.cpp b/lib/StaticAnalyzer/Core/GRState.cpp index 370f98ac56..c904ed2882 100644 --- a/lib/StaticAnalyzer/Core/GRState.cpp +++ b/lib/StaticAnalyzer/Core/GRState.cpp @@ -71,15 +71,13 @@ GRStateManager::removeDeadBindings(const GRState* state, // those around. This code more than likely can be made faster, and the // frequency of which this method is called should be experimented with // for optimum performance. - SmallVector<const MemRegion*, 10> RegionRoots; GRState NewState = *state; - NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, - state, RegionRoots); + NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, state); // Clean up the store. StoreRef newStore = StoreMgr->removeDeadBindings(NewState.getStore(), LCtx, - SymReaper, RegionRoots); + SymReaper); NewState.setStore(newStore); SymReaper.setReapedStore(newStore); diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index 852af29d81..6a039c55f5 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -373,10 +373,10 @@ public: // Part of public interface to class. /// removeDeadBindings - Scans the RegionStore of 'state' for dead values. /// It returns a new Store with these values removed. StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, - SymbolReaper& SymReaper, - SmallVectorImpl<const MemRegion*>& RegionRoots); + SymbolReaper& SymReaper); - StoreRef enterStackFrame(const GRState *state, const StackFrameContext *frame); + StoreRef enterStackFrame(const GRState *state, + const StackFrameContext *frame); //===------------------------------------------------------------------===// // Region "extents". @@ -1774,17 +1774,16 @@ bool removeDeadBindingsWorker::UpdatePostponed() { StoreRef RegionStoreManager::removeDeadBindings(Store store, const StackFrameContext *LCtx, - SymbolReaper& SymReaper, - SmallVectorImpl<const MemRegion*>& RegionRoots) -{ + SymbolReaper& SymReaper) { RegionBindings B = GetRegionBindings(store); removeDeadBindingsWorker W(*this, StateMgr, B, SymReaper, LCtx); W.GenerateClusters(); // Enqueue the region roots onto the worklist. - for (SmallVectorImpl<const MemRegion*>::iterator I=RegionRoots.begin(), - E=RegionRoots.end(); I!=E; ++I) + for (SymbolReaper::region_iterator I = SymReaper.region_begin(), + E = SymReaper.region_end(); I != E; ++I) { W.AddToWorkList(*I); + } do W.RunWorkList(); while (W.UpdatePostponed()); diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp index 7ae338e8d8..6d90d19f9e 100644 --- a/lib/StaticAnalyzer/Core/SymbolManager.cpp +++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -253,6 +253,10 @@ void SymbolReaper::markLive(SymbolRef sym) { TheDead.erase(sym); } +void SymbolReaper::markLive(const MemRegion *region) { + RegionRoots.insert(region); +} + void SymbolReaper::markInUse(SymbolRef sym) { if (isa<SymbolMetadata>(sym)) MetadataInUse.insert(sym); @@ -266,14 +270,17 @@ bool SymbolReaper::maybeDead(SymbolRef sym) { return true; } -static bool IsLiveRegion(SymbolReaper &Reaper, const MemRegion *MR) { +bool SymbolReaper::isLiveRegion(const MemRegion *MR) { + if (RegionRoots.count(MR)) + return true; + MR = MR->getBaseRegion(); if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) - return Reaper.isLive(SR->getSymbol()); + return isLive(SR->getSymbol()); if (const VarRegion *VR = dyn_cast<VarRegion>(MR)) - return Reaper.isLive(VR, true); + return isLive(VR, true); // FIXME: This is a gross over-approximation. What we really need is a way to // tell if anything still refers to this region. Unlike SymbolicRegions, @@ -304,7 +311,7 @@ bool SymbolReaper::isLive(SymbolRef sym) { } if (const SymbolExtent *extent = dyn_cast<SymbolExtent>(sym)) { - if (IsLiveRegion(*this, extent->getRegion())) { + if (isLiveRegion(extent->getRegion())) { markLive(sym); return true; } @@ -313,7 +320,7 @@ bool SymbolReaper::isLive(SymbolRef sym) { if (const SymbolMetadata *metadata = dyn_cast<SymbolMetadata>(sym)) { if (MetadataInUse.count(sym)) { - if (IsLiveRegion(*this, metadata->getRegion())) { + if (isLiveRegion(metadata->getRegion())) { markLive(sym); MetadataInUse.erase(sym); return true; |