[cfe-commits] r78284 - in /cfe/trunk: include/clang/Analysis/PathSensitive/SVals.h lib/Analysis/RegionStore.cpp
Ted Kremenek
kremenek at apple.com
Wed Aug 5 21:50:41 PDT 2009
Author: kremenek
Date: Wed Aug 5 23:50:20 2009
New Revision: 78284
URL: http://llvm.org/viewvc/llvm-project?rev=78284&view=rev
Log:
Refactor RegionStoreManager::RemoveDeadBindings to also scan the bindings of LazyCompoundSVals.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
cfe/trunk/lib/Analysis/RegionStore.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h?rev=78284&r1=78283&r2=78284&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h Wed Aug 5 23:50:20 2009
@@ -343,6 +343,9 @@
LazyCompoundVal(const LazyCompoundValData *D)
: NonLoc(LazyCompoundValKind, D) {}
public:
+ const LazyCompoundValData *getCVData() const {
+ return static_cast<const LazyCompoundValData*>(Data);
+ }
const GRState *getState() const;
const TypedRegion *getRegion() const;
Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=78284&r1=78283&r2=78284&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Wed Aug 5 23:50:20 2009
@@ -31,7 +31,7 @@
#define USE_EXPLICIT_COMPOUND 0
// Actual Store type.
-typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
+typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindings;
//===----------------------------------------------------------------------===//
// Fine-grained control of RegionStoreManager.
@@ -96,6 +96,8 @@
};
}
+typedef RegionDefaultValue::MapTy RegionDefaultBindings;
+
//===----------------------------------------------------------------------===//
// Utility functions.
//===----------------------------------------------------------------------===//
@@ -163,7 +165,7 @@
class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
const RegionStoreFeatures Features;
- RegionBindingsTy::Factory RBFactory;
+ RegionBindings::Factory RBFactory;
const MemRegion* SelfRegion;
const ImplicitParamDecl *SelfDecl;
@@ -249,9 +251,9 @@
const Expr *E, unsigned Count);
private:
- void RemoveSubRegionBindings(RegionBindingsTy &B,
- RegionDefaultValue::MapTy &DVM,
- RegionDefaultValue::MapTy::Factory &DVMFactory,
+ void RemoveSubRegionBindings(RegionBindings &B,
+ RegionDefaultBindings &DVM,
+ RegionDefaultBindings::Factory &DVMFactory,
const MemRegion *R,
RegionStoreSubRegionMap &M);
@@ -320,7 +322,7 @@
SVal RetrieveArray(const GRState *St, const TypedRegion* R);
std::pair<const GRState*, const MemRegion*>
- GetLazyBinding(RegionBindingsTy B, const MemRegion *R);
+ GetLazyBinding(RegionBindings B, const MemRegion *R);
const GRState* CopyLazyBindings(nonloc::LazyCompoundVal V,
const GRState *state,
@@ -346,8 +348,8 @@
// Utility methods.
//===------------------------------------------------------------------===//
- static inline RegionBindingsTy GetRegionBindings(Store store) {
- return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
+ static inline RegionBindings GetRegionBindings(Store store) {
+ return RegionBindings(static_cast<const RegionBindings::TreeTy*>(store));
}
void print(Store store, llvm::raw_ostream& Out, const char* nl,
@@ -394,17 +396,17 @@
RegionStoreSubRegionMap*
RegionStoreManager::getRegionStoreSubRegionMap(const GRState *state) {
- RegionBindingsTy B = GetRegionBindings(state->getStore());
+ RegionBindings B = GetRegionBindings(state->getStore());
RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
llvm::SmallVector<const SubRegion*, 10> WL;
- for (RegionBindingsTy::iterator I=B.begin(), E=B.end(); I!=E; ++I)
+ for (RegionBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I)
if (const SubRegion *R = dyn_cast<SubRegion>(I.getKey()))
M->process(WL, R);
- RegionDefaultValue::MapTy DVM = state->get<RegionDefaultValue>();
- for (RegionDefaultValue::MapTy::iterator I = DVM.begin(), E = DVM.end();
+ RegionDefaultBindings DVM = state->get<RegionDefaultValue>();
+ for (RegionDefaultBindings::iterator I = DVM.begin(), E = DVM.end();
I != E; ++I)
if (const SubRegion *R = dyn_cast<SubRegion>(I.getKey()))
M->process(WL, R);
@@ -429,9 +431,9 @@
//===----------------------------------------------------------------------===//
void
-RegionStoreManager::RemoveSubRegionBindings(RegionBindingsTy &B,
- RegionDefaultValue::MapTy &DVM,
- RegionDefaultValue::MapTy::Factory &DVMFactory,
+RegionStoreManager::RemoveSubRegionBindings(RegionBindings &B,
+ RegionDefaultBindings &DVM,
+ RegionDefaultBindings::Factory &DVMFactory,
const MemRegion *R,
RegionStoreSubRegionMap &M) {
@@ -460,9 +462,9 @@
llvm::OwningPtr<RegionStoreSubRegionMap>
SubRegions(getRegionStoreSubRegionMap(state));
- RegionBindingsTy B = GetRegionBindings(state->getStore());
- RegionDefaultValue::MapTy DVM = state->get<RegionDefaultValue>();
- RegionDefaultValue::MapTy::Factory &DVMFactory =
+ RegionBindings B = GetRegionBindings(state->getStore());
+ RegionDefaultBindings DVM = state->get<RegionDefaultValue>();
+ RegionDefaultBindings::Factory &DVMFactory =
state->get_context<RegionDefaultValue>();
RemoveSubRegionBindings(B, DVM, DVMFactory, R, *SubRegions.get());
@@ -929,8 +931,8 @@
if (const VarRegion *VR = dyn_cast<VarRegion>(R))
return CastRetrievedVal(RetrieveVar(state, VR), state, VR, T);
- RegionBindingsTy B = GetRegionBindings(state->getStore());
- RegionBindingsTy::data_type* V = B.lookup(R);
+ RegionBindings B = GetRegionBindings(state->getStore());
+ RegionBindings::data_type* V = B.lookup(R);
// Check if the region has a binding.
if (V)
@@ -958,7 +960,7 @@
}
std::pair<const GRState*, const MemRegion*>
-RegionStoreManager::GetLazyBinding(RegionBindingsTy B, const MemRegion *R) {
+RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
if (const nonloc::LazyCompoundVal *V =
dyn_cast_or_null<nonloc::LazyCompoundVal>(B.lookup(R)))
@@ -987,7 +989,7 @@
SVal RegionStoreManager::RetrieveElement(const GRState* state,
const ElementRegion* R) {
// Check if the region has a binding.
- RegionBindingsTy B = GetRegionBindings(state->getStore());
+ RegionBindings B = GetRegionBindings(state->getStore());
if (const SVal* V = B.lookup(R))
return *V;
@@ -1101,7 +1103,7 @@
QualType Ty = R->getValueType(getContext());
// Check if the region has a binding.
- RegionBindingsTy B = GetRegionBindings(state->getStore());
+ RegionBindings B = GetRegionBindings(state->getStore());
if (const SVal* V = B.lookup(R))
return *V;
@@ -1171,7 +1173,7 @@
const ObjCIvarRegion* R) {
// Check if the region has a binding.
- RegionBindingsTy B = GetRegionBindings(state->getStore());
+ RegionBindings B = GetRegionBindings(state->getStore());
if (const SVal* V = B.lookup(R))
return *V;
@@ -1194,7 +1196,7 @@
const VarRegion *R) {
// Check if the region has a binding.
- RegionBindingsTy B = GetRegionBindings(state->getStore());
+ RegionBindings B = GetRegionBindings(state->getStore());
if (const SVal* V = B.lookup(R))
return *V;
@@ -1296,7 +1298,7 @@
R = cast<loc::MemRegionVal>(L).getRegion();
if (R) {
- RegionBindingsTy B = GetRegionBindings(store);
+ RegionBindings B = GetRegionBindings(store);
return RBFactory.Remove(B, R).getRoot();
}
@@ -1339,7 +1341,7 @@
}
// Perform the binding.
- RegionBindingsTy B = GetRegionBindings(state->getStore());
+ RegionBindings B = GetRegionBindings(state->getStore());
return state->makeWithStore(RBFactory.Add(B, R, V).getRoot());
}
@@ -1499,8 +1501,8 @@
// Remove all bindings for the subregions of the struct.
Store store = state->getStore();
- RegionBindingsTy B = GetRegionBindings(store);
- for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+ RegionBindings B = GetRegionBindings(store);
+ for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
const MemRegion* R = I.getKey();
if (const SubRegion* subRegion = dyn_cast<SubRegion>(R))
if (subRegion->isSubRegionOf(R))
@@ -1521,9 +1523,9 @@
const TypedRegion *R) {
// Nuke the old bindings stemming from R.
- RegionBindingsTy B = GetRegionBindings(state->getStore());
- RegionDefaultValue::MapTy DVM = state->get<RegionDefaultValue>();
- RegionDefaultValue::MapTy::Factory &DVMFactory =
+ RegionBindings B = GetRegionBindings(state->getStore());
+ RegionDefaultBindings DVM = state->get<RegionDefaultValue>();
+ RegionDefaultBindings::Factory &DVMFactory =
state->get_context<RegionDefaultValue>();
llvm::OwningPtr<RegionStoreSubRegionMap>
@@ -1540,7 +1542,7 @@
//===----------------------------------------------------------------------===//
// State pruning.
//===----------------------------------------------------------------------===//
-
+
static void UpdateLiveSymbols(SVal X, SymbolReaper& SymReaper) {
if (loc::MemRegionVal *XR = dyn_cast<loc::MemRegionVal>(&X)) {
const MemRegion *R = XR->getRegion();
@@ -1565,13 +1567,114 @@
for (SVal::symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end();SI!=SE;++SI)
SymReaper.markLive(*SI);
}
+
+namespace {
+class VISIBILITY_HIDDEN TreeScanner {
+ RegionBindings B;
+ RegionDefaultBindings DB;
+ SymbolReaper &SymReaper;
+ llvm::DenseSet<const MemRegion*> &Marked;
+ llvm::DenseSet<const LazyCompoundValData*> &ScannedLazyVals;
+ RegionStoreSubRegionMap &M;
+ RegionStoreManager &RS;
+ llvm::SmallVectorImpl<const MemRegion*> &RegionRoots;
+ const bool MarkKeys;
+public:
+ TreeScanner(RegionBindings b, RegionDefaultBindings db,
+ SymbolReaper &symReaper,
+ llvm::DenseSet<const MemRegion*> &marked,
+ llvm::DenseSet<const LazyCompoundValData*> &scannedLazyVals,
+ RegionStoreSubRegionMap &m, RegionStoreManager &rs,
+ llvm::SmallVectorImpl<const MemRegion*> ®ionRoots,
+ bool markKeys = true)
+ : B(b), DB(db), SymReaper(symReaper), Marked(marked),
+ ScannedLazyVals(scannedLazyVals), M(m),
+ RS(rs), RegionRoots(regionRoots), MarkKeys(markKeys) {}
+
+ void scanTree(const MemRegion *R);
+};
+} // end anonymous namespace
+
+
+void TreeScanner::scanTree(const MemRegion *R) {
+ if (MarkKeys) {
+ if (Marked.count(R))
+ return;
+
+ Marked.insert(R);
+ }
+
+ // 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))
+ SymReaper.markLive(SymR->getSymbol());
+
+ // Get the data binding for R (if any).
+ const SVal* Xptr = B.lookup(R);
+
+ // Check for lazy bindings.
+ if (const nonloc::LazyCompoundVal *V =
+ dyn_cast_or_null<nonloc::LazyCompoundVal>(Xptr)) {
+
+ const LazyCompoundValData *D = V->getCVData();
+
+ if (!ScannedLazyVals.count(D)) {
+ // Scan the bindings in the LazyCompoundVal.
+ ScannedLazyVals.insert(D);
+
+ // FIXME: Cache subregion maps.
+ const GRState *lazyState = D->getState();
+
+ llvm::OwningPtr<RegionStoreSubRegionMap>
+ lazySM(RS.getRegionStoreSubRegionMap(lazyState));
+
+ Store lazyStore = lazyState->getStore();
+ RegionBindings lazyB = RS.GetRegionBindings(lazyStore);
+
+ RegionDefaultBindings lazyDB = lazyState->get<RegionDefaultValue>();
+
+ // Scan the bindings.
+ TreeScanner scan(lazyB, lazyDB, SymReaper, Marked, ScannedLazyVals,
+ *lazySM.get(), RS, RegionRoots, false);
+
+ scan.scanTree(D->getRegion());
+ }
+ }
+ else {
+ // No direct binding? Get the default binding for R (if any).
+ if (!Xptr)
+ Xptr = DB.lookup(R);
+
+ // Direct or default binding?
+ if (Xptr) {
+ SVal X = *Xptr;
+ UpdateLiveSymbols(X, SymReaper); // Update the set of live symbols.
+
+ // If X is a region, then add it to the RegionRoots.
+ if (const MemRegion *RX = X.getAsRegion()) {
+ RegionRoots.push_back(RX);
+ // Mark the super region of the RX as live.
+ // e.g.: int x; char *y = (char*) &x; if (*y) ...
+ // 'y' => element region. 'x' is its super region.
+ if (const SubRegion *SR = dyn_cast<SubRegion>(RX)) {
+ RegionRoots.push_back(SR->getSuperRegion());
+ }
+ }
+ }
+ }
+
+ RegionStoreSubRegionMap::iterator I, E;
+
+ for (llvm::tie(I, E) = M.begin_end(R); I != E; ++I)
+ scanTree(*I);
+}
void RegionStoreManager::RemoveDeadBindings(GRState &state, Stmt* Loc,
SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
{
Store store = state.getStore();
- RegionBindingsTy B = GetRegionBindings(store);
+ RegionBindings B = GetRegionBindings(store);
// Lazily constructed backmap from MemRegions to SubRegions.
typedef llvm::ImmutableSet<const MemRegion*> SubRegionsTy;
@@ -1587,14 +1690,14 @@
llvm::SmallVector<const MemRegion*, 10> IntermediateRoots;
// Scan the direct bindings for "intermediate" roots.
- for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+ for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
const MemRegion *R = I.getKey();
IntermediateRoots.push_back(R);
}
// Scan the default bindings for "intermediate" roots.
- RegionDefaultValue::MapTy DVM = state.get<RegionDefaultValue>();
- for (RegionDefaultValue::MapTy::iterator I = DVM.begin(), E = DVM.end();
+ RegionDefaultBindings DVM = state.get<RegionDefaultValue>();
+ for (RegionDefaultBindings::iterator I = DVM.begin(), E = DVM.end();
I != E; ++I) {
const MemRegion *R = I.getKey();
IntermediateRoots.push_back(R);
@@ -1627,60 +1730,21 @@
// Process the worklist of RegionRoots. This performs a "mark-and-sweep"
// of the store. We want to find all live symbols and dead regions.
- llvm::SmallPtrSet<const MemRegion*, 10> Marked;
+ llvm::DenseSet<const MemRegion*> Marked;
+ llvm::DenseSet<const LazyCompoundValData*> LazyVals;
+ TreeScanner TS(B, DVM, SymReaper, Marked, LazyVals, *SubRegions.get(),
+ *this, RegionRoots);
+
while (!RegionRoots.empty()) {
- // Dequeue the next region on the worklist.
- const MemRegion* R = RegionRoots.back();
+ const MemRegion *R = RegionRoots.back();
RegionRoots.pop_back();
+ TS.scanTree(R);
+ }
- // Check if we have already processed this region.
- if (Marked.count(R))
- continue;
-
- // Mark this region as processed. This is needed for termination in case
- // a region is referenced more than once.
- Marked.insert(R);
-
- // 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))
- SymReaper.markLive(SymR->getSymbol());
-
- // Get the data binding for R (if any).
- const SVal* Xptr = B.lookup(R);
- if (!Xptr) {
- // No direct binding? Get the default binding for R (if any).
- Xptr = DVM.lookup(R);
- }
-
- // Direct or default binding?
- if (Xptr) {
- SVal X = *Xptr;
- UpdateLiveSymbols(X, SymReaper); // Update the set of live symbols.
-
- // If X is a region, then add it to the RegionRoots.
- if (const MemRegion *RX = X.getAsRegion()) {
- RegionRoots.push_back(RX);
- // Mark the super region of the RX as live.
- // e.g.: int x; char *y = (char*) &x; if (*y) ...
- // 'y' => element region. 'x' is its super region.
- if (const SubRegion *SR = dyn_cast<SubRegion>(RX)) {
- RegionRoots.push_back(SR->getSuperRegion());
- }
- }
- }
-
- // Get the subregions of R. These are RegionRoots as well since they
- // represent values that are also bound to R.
- RegionStoreSubRegionMap::iterator I, E;
- for (llvm::tie(I, E) = SubRegions->begin_end(R); I != E; ++I)
- RegionRoots.push_back(*I);
- }
-
// We have now scanned the store, marking reachable regions and symbols
// as live. We now remove all the regions that are dead from the store
// as well as update DSymbols with the set symbols that are now dead.
- for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+ for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
const MemRegion* R = I.getKey();
// If this region live? Is so, none of its symbols are dead.
if (Marked.count(R))
@@ -1700,11 +1764,11 @@
}
// Remove dead 'default' bindings.
- RegionDefaultValue::MapTy NewDVM = DVM;
- RegionDefaultValue::MapTy::Factory &DVMFactory =
+ RegionDefaultBindings NewDVM = DVM;
+ RegionDefaultBindings::Factory &DVMFactory =
state.get_context<RegionDefaultValue>();
- for (RegionDefaultValue::MapTy::iterator I = DVM.begin(), E = DVM.end();
+ for (RegionDefaultBindings::iterator I = DVM.begin(), E = DVM.end();
I != E; ++I) {
const MemRegion *R = I.getKey();
@@ -1725,9 +1789,6 @@
SymReaper.maybeDead(*SI);
}
- // FIXME: Do a pass over nonloc::LazyCompoundVals and the symbols
- // that they reference.
-
// Write the store back.
state.setStore(store);
@@ -1744,9 +1805,9 @@
void RegionStoreManager::print(Store store, llvm::raw_ostream& OS,
const char* nl, const char *sep) {
- RegionBindingsTy B = GetRegionBindings(store);
+ RegionBindings B = GetRegionBindings(store);
OS << "Store (direct bindings):" << nl;
- for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
+ for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I)
OS << ' ' << I.getKey() << " : " << I.getData() << nl;
}
More information about the cfe-commits
mailing list