diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Analysis/BasicConstraintManager.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Analysis/BasicStore.cpp | 26 | ||||
-rw-r--r-- | clang/lib/Analysis/CFRefCount.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Analysis/Environment.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Analysis/GRExprEngine.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Analysis/GRState.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Analysis/RegionStore.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Analysis/SymbolManager.cpp | 18 |
8 files changed, 83 insertions, 84 deletions
diff --git a/clang/lib/Analysis/BasicConstraintManager.cpp b/clang/lib/Analysis/BasicConstraintManager.cpp index d9d97c601a7..450c38f20b9 100644 --- a/clang/lib/Analysis/BasicConstraintManager.cpp +++ b/clang/lib/Analysis/BasicConstraintManager.cpp @@ -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); diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp index b223114a51d..7315ec71ace 100644 --- a/clang/lib/Analysis/BasicStore.cpp +++ b/clang/lib/Analysis/BasicStore.cpp @@ -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); } } diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp index c72d2a3070b..4731921731f 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/lib/Analysis/CFRefCount.cpp @@ -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; diff --git a/clang/lib/Analysis/Environment.cpp b/clang/lib/Analysis/Environment.cpp index 5f9e97eb0a3..c4ed349906d 100644 --- a/clang/lib/Analysis/Environment.cpp +++ b/clang/lib/Analysis/Environment.cpp @@ -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(); diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index 80215f34e88..6a7f86b14bf 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -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); diff --git a/clang/lib/Analysis/GRState.cpp b/clang/lib/Analysis/GRState.cpp index 8e49ebb63db..ea6f7a03d69 100644 --- a/clang/lib/Analysis/GRState.cpp +++ b/clang/lib/Analysis/GRState.cpp @@ -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) { diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 0c6fb8098b7..7c42fec6ffb 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -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; diff --git a/clang/lib/Analysis/SymbolManager.cpp b/clang/lib/Analysis/SymbolManager.cpp index f8f85559492..d0099e15fa8 100644 --- a/clang/lib/Analysis/SymbolManager.cpp +++ b/clang/lib/Analysis/SymbolManager.cpp @@ -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); +} + |