diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-10-29 05:14:17 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-10-29 05:14:17 +0000 |
commit | 1f0a56e4c90d6e18d84042318864cbee34c3694e (patch) | |
tree | 53467b69712fe37e671c56be4f4a45059e899ecb /clang/lib/Analysis/RegionStore.cpp | |
parent | b71fae8098ecf41f1039a3a7cd71814eb1fdd7e9 (diff) | |
download | bcm5719-llvm-1f0a56e4c90d6e18d84042318864cbee34c3694e.tar.gz bcm5719-llvm-1f0a56e4c90d6e18d84042318864cbee34c3694e.zip |
Fix an insidious bug in RegionStore::RemoveDeadBindings() pointed out
by Zhongxing Xu. RemoveDeadBindings() would falsely prune
SymbolicRegions from the store that wrapped derived symbols whose
liveness could only be determined after scanning the store.
llvm-svn: 85484
Diffstat (limited to 'clang/lib/Analysis/RegionStore.cpp')
-rw-r--r-- | clang/lib/Analysis/RegionStore.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 780772a6f12..5cfe4c04100 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -1630,6 +1630,8 @@ void RegionStoreManager::RemoveDeadBindings(GRState &state, Stmt* Loc, // Process the "intermediate" roots to find if they are referenced by // real roots. llvm::SmallVector<RBDNode, 10> WorkList; + llvm::SmallVector<RBDNode, 10> Postponed; + llvm::DenseSet<const MemRegion*> IntermediateVisited; while (!IntermediateRoots.empty()) { @@ -1647,8 +1649,11 @@ void RegionStoreManager::RemoveDeadBindings(GRState &state, Stmt* Loc, } if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) { - if (SymReaper.isLive(SR->getSymbol())) - WorkList.push_back(std::make_pair(&state, SR)); + llvm::SmallVectorImpl<RBDNode> &Q = + SymReaper.isLive(SR->getSymbol()) ? WorkList : Postponed; + + Q.push_back(std::make_pair(&state, SR)); + continue; } @@ -1667,6 +1672,7 @@ void RegionStoreManager::RemoveDeadBindings(GRState &state, Stmt* Loc, llvm::DenseSet<RBDNode> Visited; +tryAgain: while (!WorkList.empty()) { RBDNode N = WorkList.back(); WorkList.pop_back(); @@ -1740,6 +1746,21 @@ void RegionStoreManager::RemoveDeadBindings(GRState &state, Stmt* Loc, } } + // See if any postponed SymbolicRegions are actually live now, after + // having done a scan. + for (llvm::SmallVectorImpl<RBDNode>::iterator I = Postponed.begin(), + E = Postponed.end() ; I != E ; ++I) { + if (const SymbolicRegion *SR = cast_or_null<SymbolicRegion>(I->second)) { + if (SymReaper.isLive(SR->getSymbol())) { + WorkList.push_back(*I); + I->second = NULL; + } + } + } + + if (!WorkList.empty()) + goto tryAgain; + // 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. |