diff options
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 780772a..dbf8c42 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -275,11 +275,11 @@ public: const GRState *BindCompoundLiteral(const GRState *state, const CompoundLiteralExpr* CL, SVal V); - const GRState *BindDecl(const GRState *ST, const VarDecl *VD, - const LocationContext *LC, SVal InitVal); + const GRState *BindDecl(const GRState *ST, const VarRegion *VR, + SVal InitVal); - const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl*, - const LocationContext *) { + const GRState *BindDeclWithNoInit(const GRState *state, + const VarRegion *) { return state; } @@ -1409,12 +1409,10 @@ const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) { } const GRState *RegionStoreManager::BindDecl(const GRState *ST, - const VarDecl *VD, - const LocationContext *LC, + const VarRegion *VR, SVal InitVal) { - QualType T = VD->getType(); - VarRegion* VR = MRMgr.getVarRegion(VD, LC); + QualType T = VR->getDecl()->getType(); if (T->isArrayType()) return BindArray(ST, VR, InitVal); @@ -1630,6 +1628,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 +1647,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 +1670,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 +1744,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. |