]> granicus.if.org Git - clang/commitdiff
Static Analyzer: Replace LiveSymbols/DeadSymbols sets with a new object called "Symbo...
authorTed Kremenek <kremenek@apple.com>
Wed, 21 Jan 2009 22:26:05 +0000 (22:26 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 21 Jan 2009 22:26:05 +0000 (22:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62722 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
include/clang/Analysis/PathSensitive/ConstraintManager.h
include/clang/Analysis/PathSensitive/Environment.h
include/clang/Analysis/PathSensitive/GRExprEngine.h
include/clang/Analysis/PathSensitive/GRState.h
include/clang/Analysis/PathSensitive/GRTransferFuncs.h
include/clang/Analysis/PathSensitive/Store.h
include/clang/Analysis/PathSensitive/SymbolManager.h
lib/Analysis/BasicConstraintManager.cpp
lib/Analysis/BasicStore.cpp
lib/Analysis/CFRefCount.cpp
lib/Analysis/Environment.cpp
lib/Analysis/GRExprEngine.cpp
lib/Analysis/GRState.cpp
lib/Analysis/RegionStore.cpp
lib/Analysis/SymbolManager.cpp

index cec7f69df3b7cb958cd52d50dfb4fa7ee58ec8a1..4cded5ce6915891cd1031ff3c0c508a481978f19 100644 (file)
@@ -46,8 +46,7 @@ public:
                        const llvm::APSInt& V) const = 0;
 
   virtual const GRState* RemoveDeadBindings(const GRState* St,
-                                    StoreManager::LiveSymbolsTy& LSymbols,
-                                    StoreManager::DeadSymbolsTy& DSymbols) = 0;
+                                            SymbolReaper& SymReaper) = 0;
 
   virtual void print(const GRState* St, std::ostream& Out, 
                      const char* nl, const char *sep) = 0;
index 7a0c88279cf502a5f17be5e68499d397362de26a..7613c9ea5f61a8c48db5b45ecab16d5fb079c717 100644 (file)
@@ -139,10 +139,10 @@ public:
   Environment BindExpr(const Environment& Env, Stmt* E, SVal V,
                        bool isBlkExpr, bool Invalidate);
 
-  Environment RemoveDeadBindings(Environment Env, Stmt* Loc,
-                              const LiveVariables& Liveness,
-                              llvm::SmallVectorImpl<const MemRegion*>& DRoots,
-                              StoreManager::LiveSymbolsTy& LSymbols);
+  Environment
+  RemoveDeadBindings(Environment Env, Stmt* Loc, SymbolReaper& SymReaper,
+                     llvm::SmallVectorImpl<const MemRegion*>& DRoots);
+
 };
   
 } // end clang namespace
index e62a75b8737d74e5925099836ee36da84d134912..05bb333cdc5463a1966d0595e106e38dec260a93 100644 (file)
@@ -55,11 +55,7 @@ protected:
   /// Liveness - live-variables information the ValueDecl* and block-level
   ///  Expr* in the CFG.  Used to prune out dead state.
   LiveVariables& Liveness;
-  
-  /// DeadSymbols - A scratch set used to record the set of symbols that
-  ///  were just marked dead by a call to GRStateManager::RemoveDeadBindings.
-  GRStateManager::DeadSymbolsTy DeadSymbols;
-  
+
   /// Builder - The current GRStmtNodeBuilder which is used when building the
   ///  nodes for a given statement.
   StmtNodeBuilder* Builder;
index 59de60084d6fee6b0f6fba0399032e7804b7150f..7cf3a43bfa8f078713aaa7bbd074ef6fdc53c777 100644 (file)
@@ -334,8 +334,6 @@ public:
   MemRegionManager& getRegionManager() { return StoreMgr->getRegionManager(); }
   StoreManager& getStoreManager() { return *StoreMgr; }
 
-  typedef StoreManager::DeadSymbolsTy DeadSymbolsTy;
-
   const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal IVal) {
     // Store manager should return a persistent state.
     return StoreMgr->BindDecl(St, VD, IVal);
@@ -356,8 +354,7 @@ public:
   }
 
   const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc, 
-                                    const LiveVariables& Liveness,
-                                    DeadSymbolsTy& DeadSyms);
+                                    SymbolReaper& SymReaper);
 
   const GRState* RemoveSubExprBindings(const GRState* St) {
     GRState NewSt = *St;
index 8f6a75a8ab6776880319e723933790d383da57c0..6f4266b9df6fa5455a97c2c8dd1333a1851f9d0e 100644 (file)
@@ -108,9 +108,8 @@ public:
                                GRExprEngine& Engine,
                                GRStmtNodeBuilder<GRState>& Builder,
                                ExplodedNode<GRState>* Pred,
-                               Stmt* S,
-                               const GRState* St,
-                               const GRStateManager::DeadSymbolsTy& Dead) {}
+                               Stmt* S, const GRState* state,
+                               SymbolReaper& SymReaper) {}
   
   // Return statements.  
   virtual void EvalReturn(ExplodedNodeSet<GRState>& Dst,
index b43699e72bf98e3c604889eb3b1f69e321a89aa7..b8d6364388fb5c5cdc0e2a78641f5d5040fac1b5 100644 (file)
@@ -28,16 +28,11 @@ typedef const void* Store;
 
 class GRState;  
 class GRStateManager;
-class LiveVariables;
 class Stmt;
 class Expr;
 class ObjCIvarDecl;
 
 class StoreManager {
-public:
-  typedef llvm::SmallSet<SymbolRef, 20>      LiveSymbolsTy;
-  typedef llvm::DenseSet<SymbolRef>          DeadSymbolsTy;
-
 protected:
   /// MRMgr - Manages region objects associated with this StoreManager.
   MemRegionManager MRMgr;
@@ -55,12 +50,7 @@ public:
   ///   lazily computed.
   /// \return The value bound to the location \c loc.
   virtual SVal Retrieve(const GRState* state, Loc loc,
-                        QualType T = QualType()) = 0;  
-
-//  /// Retrieves the value bound to the specified region.
-//  SVal GetRegionSVal(const GRState* state, const MemRegion* R) {
-//    return Retrieve(state, loc::MemRegionVal(R));
-//  }
+                        QualType T = QualType()) = 0;
 
   /// Return a state with the specified value bound to the given location.
   /// \param[in] state The analysis state.
@@ -129,9 +119,8 @@ public:
   virtual const MemRegion* getSelfRegion(Store store) = 0;
 
   virtual Store
-  RemoveDeadBindings(const GRState* state, Stmt* Loc, const LiveVariables& Live,
-                     llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
-                     LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols) = 0;
+  RemoveDeadBindings(const GRState* state, Stmt* Loc, SymbolReaper& SymReaper,
+                     llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
 
   virtual const GRState* BindDecl(const GRState* St, const VarDecl* VD, 
                                   SVal InitVal) = 0;
index 87852934945cd071c8e4ee299472d59973f6040f..e326166dfc9db61c402c0a9906caf7330f4aa948 100644 (file)
 
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/DenseMap.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ImmutableSet.h"
 
 namespace llvm {
   class raw_ostream;
@@ -292,7 +294,44 @@ public:
     return getSymbolData(ID).getType(*this);
   }
 };
+  
+class SymbolReaper {
+  typedef llvm::ImmutableSet<SymbolRef> SetTy;
+  typedef SetTy::Factory FactoryTy;
+  
+  FactoryTy F;
+  SetTy TheLiving;
+  SetTy TheDead;
+  LiveVariables& Liveness;
+  SymbolManager& SymMgr;
+  
+public:
+  SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr)
+  : TheLiving(F.GetEmptySet()), TheDead(F.GetEmptySet()),
+    Liveness(liveness), SymMgr(symmgr) {}
+
+  bool isLive(SymbolRef sym);
 
+  bool isLive(const Stmt* Loc, const Stmt* ExprVal) const {
+    return Liveness.isLive(Loc, ExprVal);
+  }
+
+  bool isLive(const Stmt* Loc, const VarDecl* VD) const {
+    return Liveness.isLive(Loc, VD);
+  }
+  
+  void markLive(SymbolRef sym);
+  bool maybeDead(SymbolRef sym);
+  
+  typedef SetTy::iterator dead_iterator;
+  dead_iterator dead_begin() const { return TheDead.begin(); }
+  dead_iterator dead_end() const { return TheDead.end(); }
+  
+  bool hasDeadSymbols() const {
+    return !TheDead.isEmpty();
+  }
+};
+  
 } // end clang namespace
 
 #endif
index d9d97c601a7461bd04ef862f2df528f4ae7580af..450c38f20b96d3c39728330301649149ae837948 100644 (file)
@@ -82,9 +82,8 @@ public:
   bool isNotEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
   bool isEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
 
-  const GRState* RemoveDeadBindings(const GRState* St,
-                                    StoreManager::LiveSymbolsTy& LSymbols,
-                                    StoreManager::DeadSymbolsTy& DSymbols);
+  const GRState* RemoveDeadBindings(const GRState* St, SymbolReaper& SymReaper);
+
 
   void print(const GRState* St, std::ostream& Out, 
              const char* nl, const char *sep);
@@ -504,19 +503,17 @@ bool BasicConstraintManager::isEqual(const GRState* St, SymbolRef sym,
 
 /// Scan all symbols referenced by the constraints. If the symbol is not alive
 /// as marked in LSymbols, mark it as dead in DSymbols.
-const GRState* BasicConstraintManager::RemoveDeadBindings(const GRState* St,
-                                        StoreManager::LiveSymbolsTy& LSymbols,
-                                        StoreManager::DeadSymbolsTy& DSymbols) {
+const GRState*
+BasicConstraintManager::RemoveDeadBindings(const GRState* St,
+                                           SymbolReaper& SymReaper) {
+
   GRStateRef state(St, StateMgr);
   ConstEqTy CE = state.get<ConstEqTy>();
   ConstEqTy::Factory& CEFactory = state.get_context<ConstEqTy>();
 
   for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
-    SymbolRef sym = I.getKey();        
-    if (!LSymbols.count(sym)) {
-      DSymbols.insert(sym);
-      CE = CEFactory.Remove(CE, sym);
-    }
+    SymbolRef sym = I.getKey();
+    if (SymReaper.maybeDead(sym)) CE = CEFactory.Remove(CE, sym);
   }
   state = state.set<ConstEqTy>(CE);
 
@@ -525,10 +522,7 @@ const GRState* BasicConstraintManager::RemoveDeadBindings(const GRState* St,
 
   for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
     SymbolRef sym = I.getKey();    
-    if (!LSymbols.count(sym)) {
-      DSymbols.insert(sym);
-      CNE = CNEFactory.Remove(CNE, sym);
-    }
+    if (SymReaper.maybeDead(sym)) CNE = CNEFactory.Remove(CNE, sym);
   }
   
   return state.set<ConstNotEqTy>(CNE);
index b223114a51d8096ab458f049bb7c55facabb9bf1..7315ec71ace56a327e018bc950374b33aa8ff092 100644 (file)
@@ -88,10 +88,10 @@ public:
   /// RemoveDeadBindings - Scans a BasicStore of 'state' for dead values.
   ///  It returns a new Store with these values removed, and populates LSymbols
   ///  and DSymbols with the known set of live and dead symbols respectively.
-  Store RemoveDeadBindings(const GRState* state, Stmt* Loc,
-                           const LiveVariables& Live,
-                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
-                           LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols);
+  Store
+  RemoveDeadBindings(const GRState* state, Stmt* Loc,
+                     SymbolReaper& SymReaper,
+                     llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
 
   void iterBindings(Store store, BindingsHandler& f);
 
@@ -344,9 +344,9 @@ Store BasicStoreManager::Remove(Store store, Loc loc) {
 
 Store
 BasicStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
-                          const LiveVariables& Liveness,
-                          llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
-                          LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols) {
+                                      SymbolReaper& SymReaper,
+                          llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
+{
   
   Store store = state->getStore();
   VarBindingsTy B = GetVarBindings(store);
@@ -354,12 +354,12 @@ BasicStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
   
   // Iterate over the variable bindings.
   for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
-    if (Liveness.isLive(Loc, I.getKey())) {
+    if (SymReaper.isLive(Loc, I.getKey())) {
       RegionRoots.push_back(MRMgr.getVarRegion(I.getKey()));      
       SVal X = I.getData();
       
       for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
-        LSymbols.insert(*SI);
+        SymReaper.markLive(*SI);
     }
   
   // Scan for live variables and live symbols.
@@ -371,7 +371,7 @@ BasicStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
     
     while (MR) {
       if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(MR)) {
-        LSymbols.insert(SymR->getSymbol());
+        SymReaper.markLive(SymR->getSymbol());
         break;
       }
       else if (const VarRegion* R = dyn_cast<VarRegion>(MR)) {
@@ -382,8 +382,8 @@ BasicStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
         SVal X = Retrieve(state, loc::MemRegionVal(R));
     
         // FIXME: We need to handle symbols nested in region definitions.
-        for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
-          LSymbols.insert(*SI);
+        for (symbol_iterator SI=X.symbol_begin(),SE=X.symbol_end();SI!=SE;++SI)
+          SymReaper.markLive(*SI);
     
         if (!isa<loc::MemRegionVal>(X))
           break;
@@ -408,7 +408,7 @@ BasicStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
       SVal X = I.getData();
       
       for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
-        if (!LSymbols.count(*SI)) DSymbols.insert(*SI);
+        SymReaper.maybeDead(*SI);
     }
   }
   
index c72d2a3070b47b415e6b51fdd00f2196247dc5b4..4731921731faf2ecdebc3d61687bcece2699fce0 100644 (file)
@@ -1367,9 +1367,9 @@ public:
                                GRExprEngine& Engine,
                                GRStmtNodeBuilder<GRState>& Builder,
                                ExplodedNode<GRState>* Pred,
-                               Stmt* S,
-                               const GRState* St,
-                               const GRStateManager::DeadSymbolsTy& Dead);
+                               Stmt* S, const GRState* state,
+                               SymbolReaper& SymReaper);
+
   // Return statements.
   
   virtual void EvalReturn(ExplodedNodeSet<GRState>& Dst,
@@ -1915,20 +1915,18 @@ void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
                                  ExplodedNode<GRState>* Pred,
                                  Stmt* S,
                                  const GRState* St,
-                                 const GRStateManager::DeadSymbolsTy& Dead) {
+                                 SymbolReaper& SymReaper) {
     
   // FIXME: a lot of copy-and-paste from EvalEndPath.  Refactor.
   
   RefBindings B = St->get<RefBindings>();
   llvm::SmallVector<std::pair<SymbolRef,bool>, 10> Leaked;
   
-  for (GRStateManager::DeadSymbolsTy::const_iterator
-       I=Dead.begin(), E=Dead.end(); I!=E; ++I) {
+  for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
+        E = SymReaper.dead_end(); I != E; ++I) {
     
     const RefVal* T = B.lookup(*I);
-
-    if (!T)
-      continue;
+    if (!T) continue;
     
     bool hasLeak = false;
     
index 5f9e97eb0a3334fcceb954061b8fc1ec21829ca9..c4ed349906d6b020a2daee8d626777f370eb39c8 100644 (file)
@@ -108,9 +108,8 @@ Environment EnvironmentManager::BindExpr(const Environment& Env, Stmt* E,SVal V,
 
 Environment 
 EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
-                                const LiveVariables& Liveness,
-                                llvm::SmallVectorImpl<const MemRegion*>& DRoots,
-                                StoreManager::LiveSymbolsTy& LSymbols) {
+                                       SymbolReaper& SymReaper,
+                              llvm::SmallVectorImpl<const MemRegion*>& DRoots) {
   
   // Drop bindings for subexpressions.
   Env = RemoveSubExprBindings(Env);
@@ -120,19 +119,18 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
        I != E; ++I) {
     Stmt* BlkExpr = I.getKey();
 
-    if (Liveness.isLive(Loc, BlkExpr)) {
+    if (SymReaper.isLive(Loc, BlkExpr)) {
       SVal X = I.getData();
 
       // If the block expr's value is a memory region, then mark that region.
       if (isa<loc::MemRegionVal>(X))
         DRoots.push_back(cast<loc::MemRegionVal>(X).getRegion());
 
-
       // Mark all symbols in the block expr's value.
       for (SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
-           SI != SE; ++SI) {
-        LSymbols.insert(*SI);
-      }
+           SI != SE; ++SI)
+        SymReaper.markLive(*SI);
+
     } else {
       // The block expr is dead.
       SVal X = I.getData();
index 80215f34e888e88782d11ae927e05e5b6219d08f..6a7f86b14bf00d7484a7e3931a4435e19badd115 100644 (file)
@@ -211,18 +211,17 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
   if (BatchAuditor)
     Builder->setAuditor(BatchAuditor.get());
   
+    
   // Create the cleaned state.  
-  if (PurgeDead)
-    CleanedState = StateMgr.RemoveDeadBindings(EntryNode->getState(), 
-                                               CurrentStmt,
-                                               Liveness, DeadSymbols);
-  else
-    CleanedState = EntryNode->getState();
-  
+  SymbolReaper SymReaper(Liveness, SymMgr);  
+  CleanedState = PurgeDead ? StateMgr.RemoveDeadBindings(EntryNode->getState(), 
+                                                         CurrentStmt, SymReaper)
+                           : EntryNode->getState();
+
   // Process any special transfer function for dead symbols.
   NodeSet Tmp;
   
-  if (DeadSymbols.empty())
+  if (!SymReaper.hasDeadSymbols())
     Tmp.Add(EntryNode);
   else {
     SaveAndRestore<bool> OldSink(Builder->BuildSinks);
@@ -232,7 +231,7 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
     Builder->PurgingDeadSymbols = true;
     
     getTF().EvalDeadSymbols(Tmp, *this, *Builder, EntryNode, S, 
-                        CleanedState, DeadSymbols);
+                            CleanedState, SymReaper);
 
     if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
       Tmp.Add(EntryNode);
index 8e49ebb63db31043189d4642c19ca9a91d9ede54..ea6f7a03d6915849f501f19cad1ef1ad3db9c9ba 100644 (file)
@@ -34,9 +34,8 @@ GRStateManager::~GRStateManager() {
 
 const GRState*
 GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
-                                   const LiveVariables& Liveness,
-                                   DeadSymbolsTy& DSymbols) {  
-  
+                                   SymbolReaper& SymReaper) {
+
   // This code essentially performs a "mark-and-sweep" of the VariableBindings.
   // The roots are any Block-level exprs and Decls that our liveness algorithm
   // tells us are live.  We then see what Decls they may reference, and keep
@@ -44,19 +43,17 @@ GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
   // frequency of which this method is called should be experimented with
   // for optimum performance.
   llvm::SmallVector<const MemRegion*, 10> RegionRoots;
-  StoreManager::LiveSymbolsTy LSymbols;
   GRState NewState = *state;
 
-  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, Liveness,
-                                           RegionRoots, LSymbols);
+  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper,
+                                           RegionRoots);
 
   // Clean up the store.
-  DSymbols.clear();
-  NewState.St = StoreMgr->RemoveDeadBindings(&NewState, Loc, Liveness,
-                                             RegionRoots, LSymbols, DSymbols);
+  NewState.St = StoreMgr->RemoveDeadBindings(&NewState, Loc, SymReaper,
+                                             RegionRoots);
 
   return ConstraintMgr->RemoveDeadBindings(getPersistentState(NewState),
-                                           LSymbols, DSymbols);
+                                           SymReaper);
 }
 
 const GRState* GRStateManager::Unbind(const GRState* St, Loc LV) {
index 0c6fb8098b75586be10005c6ae3eb32e5cc533e8..7c42fec6ffbddb4b911ac1c6bb2d6add9851acf7 100644 (file)
@@ -195,11 +195,8 @@ public:
   ///  It returns a new Store with these values removed, and populates LSymbols
   //   and DSymbols with the known set of live and dead symbols respectively.
   Store RemoveDeadBindings(const GRState* state, Stmt* Loc,
-                           const LiveVariables& Live,
-                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
-                           LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols);
-
-  void UpdateLiveSymbols(SVal X, LiveSymbolsTy& LSymbols);
+                           SymbolReaper& SymReaper,
+                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
 
   const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal);
 
@@ -696,15 +693,15 @@ const GRState* RegionStoreManager::setExtent(const GRState* St,
 }
 
 
-void RegionStoreManager::UpdateLiveSymbols(SVal X, LiveSymbolsTy& LSymbols) {
-  for (SVal::symbol_iterator SI=X.symbol_begin(),SE=X.symbol_end();SI!=SE;++SI)
-    LSymbols.insert(*SI);
+static void UpdateLiveSymbols(SVal X, SymbolReaper& SymReaper) {
+  for (SVal::symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end();SI!=SE;++SI)
+    SymReaper.markLive(*SI);
 }
 
 Store RegionStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc, 
-                                             const LiveVariables& Live,
-                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
-                           LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols) {
+                                             SymbolReaper& SymReaper,
+                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
+{
 
   Store store = state->getStore();
   RegionBindingsTy B = GetRegionBindings(store);
@@ -732,7 +729,7 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
   for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
     const MemRegion* R = I.getKey();
     if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
-      if (Live.isLive(Loc, VR->getDecl()))
+      if (SymReaper.isLive(Loc, VR->getDecl()))
         RegionRoots.push_back(VR); // This is a live "root".
     }
     else {
@@ -748,7 +745,7 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
       // to also mark SuperR as a root (as it may not have a value directly
       // bound to it in the store).
       if (const VarRegion* VR = dyn_cast<VarRegion>(SuperR)) {
-        if (Live.isLive(Loc, VR->getDecl()))
+        if (SymReaper.isLive(Loc, VR->getDecl()))
           RegionRoots.push_back(VR); // This is a live "root".
       }
     } 
@@ -773,13 +770,13 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
     // Mark the symbol for any live SymbolicRegion as "live".  This means we
     // should continue to track that symbol.
     if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
-      LSymbols.insert(SymR->getSymbol());
+      SymReaper.markLive(SymR->getSymbol());
 
     // Get the data binding for R (if any).
     RegionBindingsTy::data_type* Xptr = B.lookup(R);
     if (Xptr) {
       SVal X = *Xptr;
-      UpdateLiveSymbols(X, LSymbols); // Update the set of live symbols.
+      UpdateLiveSymbols(X, SymReaper); // Update the set of live symbols.
     
       // If X is a region, then add it the RegionRoots.
       if (loc::MemRegionVal* RegionX = dyn_cast<loc::MemRegionVal>(&X))
@@ -811,14 +808,12 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
     store = Remove(store, Loc::MakeVal(R));
 
     // Mark all non-live symbols that this region references as dead.
-    if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R)) {
-      SymbolRef Sym = SymR->getSymbol();
-      if (!LSymbols.count(Sym)) DSymbols.insert(Sym);
-    }
+    if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
+      SymReaper.maybeDead(SymR->getSymbol());
 
     SVal X = I.getData();
     SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
-    for (; SI != SE; ++SI) { if (!LSymbols.count(*SI)) DSymbols.insert(*SI); }
+    for (; SI != SE; ++SI) SymReaper.maybeDead(*SI);
   }
   
   return store;
index f8f855594929e5b6be9cde91772a6efc17c92404..d0099e15fa8fa416bf8d1ef896f7bc88b578604f 100644 (file)
@@ -158,3 +158,21 @@ QualType SymbolData::getType(const SymbolManager& SymMgr) const {
 }
 
 SymbolManager::~SymbolManager() {}
+
+void SymbolReaper::markLive(SymbolRef sym) {
+  TheLiving = F.Add(TheLiving, sym);
+  TheDead = F.Remove(TheDead, sym);
+}
+
+bool SymbolReaper::maybeDead(SymbolRef sym) {
+  if (isLive(sym))
+    return false;
+  
+  TheDead = F.Add(TheDead, sym);
+  return true;
+}
+
+bool SymbolReaper::isLive(SymbolRef sym) {  
+  return TheLiving.contains(sym);
+}
+