forked from OSchip/llvm-project
Implement FIXME: GRStateManager::scanReachableSymbols now supports scanning MemRegions.
llvm-svn: 65919
This commit is contained in:
parent
d62491a808
commit
4c8a5817a5
|
@ -141,7 +141,7 @@ public:
|
|||
|
||||
Environment
|
||||
RemoveDeadBindings(Environment Env, Stmt* Loc, SymbolReaper& SymReaper,
|
||||
GRStateManager& StateMgr,
|
||||
GRStateManager& StateMgr, const GRState *state,
|
||||
llvm::SmallVectorImpl<const MemRegion*>& DRoots);
|
||||
|
||||
};
|
||||
|
|
|
@ -611,8 +611,8 @@ public:
|
|||
ConstraintMgr->EndPath(St);
|
||||
}
|
||||
|
||||
bool scanReachableSymbols(nonloc::CompoundVal val, SymbolVisitor& vistor);
|
||||
bool scanReachableSymbols(SVal val, SymbolVisitor& visitor);
|
||||
bool scanReachableSymbols(SVal val, const GRState* state,
|
||||
SymbolVisitor& visitor);
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -738,7 +738,7 @@ public:
|
|||
template <typename CB>
|
||||
CB scanReachableSymbols(SVal val) {
|
||||
CB cb(*this);
|
||||
Mgr->scanReachableSymbols(val, cb);
|
||||
Mgr->scanReachableSymbols(val, St, cb);
|
||||
return cb;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,11 +170,11 @@ public:
|
|||
|
||||
class Visitor {
|
||||
public:
|
||||
virtual ~Visitor() {}
|
||||
virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion);
|
||||
virtual ~Visitor() {};
|
||||
virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0;
|
||||
};
|
||||
|
||||
virtual void iterSubRegions(const MemRegion* R, Visitor& V) const = 0;
|
||||
virtual bool iterSubRegions(const MemRegion* R, Visitor& V) const = 0;
|
||||
};
|
||||
|
||||
StoreManager* CreateBasicStoreManager(GRStateManager& StMgr);
|
||||
|
|
|
@ -27,8 +27,9 @@ class VISIBILITY_HIDDEN BasicStoreSubRegionMap : public SubRegionMap {
|
|||
public:
|
||||
BasicStoreSubRegionMap() {}
|
||||
|
||||
void iterSubRegions(const MemRegion* R, Visitor& V) const {
|
||||
bool iterSubRegions(const MemRegion* R, Visitor& V) const {
|
||||
// Do nothing. No subregions.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ Environment
|
|||
EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
|
||||
SymbolReaper& SymReaper,
|
||||
GRStateManager& StateMgr,
|
||||
const GRState *state,
|
||||
llvm::SmallVectorImpl<const MemRegion*>& DRoots) {
|
||||
|
||||
// Drop bindings for subexpressions.
|
||||
|
@ -138,7 +139,7 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
|
|||
|
||||
// Mark all symbols in the block expr's value live.
|
||||
MarkLiveCallback cb(SymReaper);
|
||||
StateMgr.scanReachableSymbols(X, cb);
|
||||
StateMgr.scanReachableSymbols(X, state, cb);
|
||||
} else {
|
||||
// The block expr is dead.
|
||||
SVal X = I.getData();
|
||||
|
|
|
@ -46,7 +46,7 @@ GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
|
|||
GRState NewState = *state;
|
||||
|
||||
NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper, *this,
|
||||
RegionRoots);
|
||||
state, RegionRoots);
|
||||
|
||||
// Clean up the store.
|
||||
NewState.St = StoreMgr->RemoveDeadBindings(&NewState, Loc, SymReaper,
|
||||
|
@ -208,19 +208,42 @@ const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
|
|||
// Utility.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool GRStateManager::scanReachableSymbols(nonloc::CompoundVal val,
|
||||
SymbolVisitor& visitor) {
|
||||
namespace {
|
||||
class VISIBILITY_HIDDEN ScanReachableSymbols : public SubRegionMap::Visitor {
|
||||
typedef llvm::DenseSet<const MemRegion*> VisitedRegionsTy;
|
||||
|
||||
VisitedRegionsTy visited;
|
||||
GRStateRef state;
|
||||
SymbolVisitor &visitor;
|
||||
llvm::OwningPtr<SubRegionMap> SRM;
|
||||
public:
|
||||
|
||||
ScanReachableSymbols(GRStateManager* sm, const GRState *st, SymbolVisitor& v)
|
||||
: state(st, *sm), visitor(v) {}
|
||||
|
||||
bool scan(nonloc::CompoundVal val);
|
||||
bool scan(SVal val);
|
||||
bool scan(const MemRegion *R);
|
||||
|
||||
// From SubRegionMap::Visitor.
|
||||
bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
|
||||
return scan(SubRegion);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
|
||||
for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
|
||||
if (!scanReachableSymbols(*I, visitor)) return false;
|
||||
if (!scan(*I))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GRStateManager::scanReachableSymbols(SVal val, SymbolVisitor& visitor) {
|
||||
|
||||
// FIXME: Scan through through the reachable regions.
|
||||
// if (isa<Loc>(val)) { ... }
|
||||
|
||||
|
||||
bool ScanReachableSymbols::scan(SVal val) {
|
||||
if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
|
||||
return scan(X->getRegion());
|
||||
|
||||
if (loc::SymbolVal *X = dyn_cast<loc::SymbolVal>(&val))
|
||||
return visitor.VisitSymbol(X->getSymbol());
|
||||
|
||||
|
@ -228,10 +251,43 @@ bool GRStateManager::scanReachableSymbols(SVal val, SymbolVisitor& visitor) {
|
|||
return visitor.VisitSymbol(X->getSymbol());
|
||||
|
||||
if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
|
||||
return scanReachableSymbols(*X, visitor);
|
||||
return scan(*X);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScanReachableSymbols::scan(const MemRegion *R) {
|
||||
if (visited.count(R))
|
||||
return true;
|
||||
|
||||
visited.insert(R);
|
||||
|
||||
// If this is a symbolic region, visit the symbol for the region.
|
||||
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
|
||||
if (!visitor.VisitSymbol(SR->getSymbol()))
|
||||
return false;
|
||||
|
||||
// If this is a subregion, also visit the parent regions.
|
||||
if (const SubRegion *SR = dyn_cast<SubRegion>(R))
|
||||
if (!scan(SR->getSuperRegion()));
|
||||
return false;
|
||||
|
||||
// Now look at the binding to this region (if any).
|
||||
if (!scan(state.GetSVal(R)))
|
||||
return false;
|
||||
|
||||
// Now look at the subregions.
|
||||
if (!SRM.get())
|
||||
SRM.reset(state.getManager().getStoreManager().getSubRegionMap(state).get());
|
||||
|
||||
return SRM->iterSubRegions(R, *this);
|
||||
}
|
||||
|
||||
bool GRStateManager::scanReachableSymbols(SVal val, const GRState* state,
|
||||
SymbolVisitor& visitor) {
|
||||
ScanReachableSymbols S(this, state, visitor);
|
||||
return S.scan(val);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Queries.
|
||||
|
|
|
@ -121,18 +121,20 @@ public:
|
|||
|
||||
~RegionStoreSubRegionMap() {}
|
||||
|
||||
void iterSubRegions(const MemRegion* Parent, Visitor& V) const {
|
||||
bool iterSubRegions(const MemRegion* Parent, Visitor& V) const {
|
||||
Map::iterator I = M.find(Parent);
|
||||
|
||||
if (I == M.end())
|
||||
return;
|
||||
return true;
|
||||
|
||||
llvm::ImmutableSet<const MemRegion*> S = I->second;
|
||||
for (llvm::ImmutableSet<const MemRegion*>::iterator SI=S.begin(),SE=S.end();
|
||||
SI != SE; ++SI) {
|
||||
if (!V.Visit(Parent, *SI))
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -600,10 +602,8 @@ RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
|
|||
|
||||
SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
|
||||
// Assume the base location is MemRegionVal(ElementRegion).
|
||||
|
||||
if (!isa<loc::MemRegionVal>(L)) {
|
||||
if (!isa<loc::MemRegionVal>(L))
|
||||
return UnknownVal();
|
||||
}
|
||||
|
||||
const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
|
||||
|
||||
|
@ -621,8 +621,9 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
|
|||
ER->getArrayRegion());
|
||||
return Loc::MakeVal(NewER);
|
||||
|
||||
} else
|
||||
return UnknownVal();
|
||||
}
|
||||
|
||||
return UnknownVal();
|
||||
}
|
||||
|
||||
SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
|
||||
|
|
Loading…
Reference in New Issue