summaryrefslogtreecommitdiff
path: root/lib/Analysis/GRState.cpp
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
commit4c8b24812ddcd1dedaca343a6d4e76f91f398981 (patch)
tree137ebebcae16fb0ce7ab4af456992bbd8d22fced /lib/Analysis/GRState.cpp
parent5362a71c02e7d448a8ce98cf00c47e353fba5d04 (diff)
Notes
Diffstat (limited to 'lib/Analysis/GRState.cpp')
-rw-r--r--lib/Analysis/GRState.cpp158
1 files changed, 72 insertions, 86 deletions
diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp
index 54c0afbff33ee..f269824d5477c 100644
--- a/lib/Analysis/GRState.cpp
+++ b/lib/Analysis/GRState.cpp
@@ -27,7 +27,7 @@ GRStateManager::~GRStateManager() {
for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
E=Printers.end(); I!=E; ++I)
delete *I;
-
+
for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
I!=E; ++I)
I->second.second(I->second.first);
@@ -46,12 +46,11 @@ GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
llvm::SmallVector<const MemRegion*, 10> RegionRoots;
GRState NewState = *state;
- NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper, *this,
+ NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper,
state, RegionRoots);
// Clean up the store.
- NewState.St = StoreMgr->RemoveDeadBindings(&NewState, Loc, SymReaper,
- RegionRoots);
+ StoreMgr->RemoveDeadBindings(NewState, Loc, SymReaper, RegionRoots);
return ConstraintMgr->RemoveDeadBindings(getPersistentState(NewState),
SymReaper);
@@ -59,14 +58,14 @@ GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
const GRState *GRState::unbindLoc(Loc LV) const {
Store OldStore = getStore();
- Store NewStore = Mgr->StoreMgr->Remove(OldStore, LV);
-
+ Store NewStore = getStateManager().StoreMgr->Remove(OldStore, LV);
+
if (NewStore == OldStore)
return this;
-
+
GRState NewSt = *this;
NewSt.St = NewStore;
- return Mgr->getPersistentState(NewSt);
+ return getStateManager().getPersistentState(NewSt);
}
SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
@@ -77,7 +76,7 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
return UnknownVal();
if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
- QualType T = TR->getValueType(Mgr->getContext());
+ QualType T = TR->getValueType(getStateManager().getContext());
if (Loc::IsLocType(T) || T->isIntegerType())
return getSVal(R);
}
@@ -86,55 +85,37 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
}
-const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr,
- bool Invalidate) const {
-
- Environment NewEnv = Mgr->EnvMgr.BindExpr(Env, Ex, V, isBlkExpr, Invalidate);
-
+const GRState *GRState::BindExpr(const Stmt* Ex, SVal V, bool Invalidate) const{
+ Environment NewEnv = getStateManager().EnvMgr.BindExpr(Env, Ex, V,
+ Invalidate);
if (NewEnv == Env)
return this;
-
+
GRState NewSt = *this;
NewSt.Env = NewEnv;
- return Mgr->getPersistentState(NewSt);
-}
-
-const GRState *GRState::bindExpr(const Stmt* Ex, SVal V,
- bool Invalidate) const {
-
- bool isBlkExpr = false;
-
- if (Ex == Mgr->CurrentStmt) {
- // FIXME: Should this just be an assertion? When would we want to set
- // the value of a block-level expression if it wasn't CurrentStmt?
- isBlkExpr = Mgr->cfg.isBlkExpr(Ex);
-
- if (!isBlkExpr)
- return this;
- }
-
- return bindExpr(Ex, V, isBlkExpr, Invalidate);
+ return getStateManager().getPersistentState(NewSt);
}
-const GRState* GRStateManager::getInitialState() {
- GRState StateImpl(this, EnvMgr.getInitialEnvironment(),
- StoreMgr->getInitialStore(),
- GDMFactory.GetEmptyMap());
+const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {
+ GRState State(this,
+ EnvMgr.getInitialEnvironment(InitLoc->getAnalysisContext()),
+ StoreMgr->getInitialStore(InitLoc),
+ GDMFactory.GetEmptyMap());
- return getPersistentState(StateImpl);
+ return getPersistentState(State);
}
const GRState* GRStateManager::getPersistentState(GRState& State) {
-
+
llvm::FoldingSetNodeID ID;
- State.Profile(ID);
+ State.Profile(ID);
void* InsertPos;
-
+
if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
return I;
-
+
GRState* I = (GRState*) Alloc.Allocate<GRState>();
- new (I) GRState(State);
+ new (I) GRState(State);
StateSet.InsertNode(I, InsertPos);
return I;
}
@@ -142,7 +123,7 @@ const GRState* GRStateManager::getPersistentState(GRState& State) {
const GRState* GRState::makeWithStore(Store store) const {
GRState NewSt = *this;
NewSt.St = store;
- return Mgr->getPersistentState(NewSt);
+ return getStateManager().getPersistentState(NewSt);
}
//===----------------------------------------------------------------------===//
@@ -150,51 +131,56 @@ const GRState* GRState::makeWithStore(Store store) const {
//===----------------------------------------------------------------------===//
void GRState::print(llvm::raw_ostream& Out, const char* nl,
- const char* sep) const {
+ const char* sep) const {
// Print the store.
- Mgr->getStoreManager().print(getStore(), Out, nl, sep);
-
+ GRStateManager &Mgr = getStateManager();
+ Mgr.getStoreManager().print(getStore(), Out, nl, sep);
+
+ CFG &C = *getAnalysisContext().getCFG();
+
// Print Subexpression bindings.
bool isFirst = true;
-
- for (seb_iterator I = seb_begin(), E = seb_end(); I != E; ++I) {
-
+
+ for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
+ if (C.isBlkExpr(I.getKey()))
+ continue;
+
if (isFirst) {
Out << nl << nl << "Sub-Expressions:" << nl;
isFirst = false;
}
else { Out << nl; }
-
+
Out << " (" << (void*) I.getKey() << ") ";
LangOptions LO; // FIXME.
I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
- Out << " : ";
- I.getData().print(Out);
+ Out << " : " << I.getData();
}
-
+
// Print block-expression bindings.
isFirst = true;
-
- for (beb_iterator I = beb_begin(), E = beb_end(); I != E; ++I) {
+
+ for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
+ if (!C.isBlkExpr(I.getKey()))
+ continue;
if (isFirst) {
Out << nl << nl << "Block-level Expressions:" << nl;
isFirst = false;
}
else { Out << nl; }
-
+
Out << " (" << (void*) I.getKey() << ") ";
LangOptions LO; // FIXME.
I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
- Out << " : ";
- I.getData().print(Out);
+ Out << " : " << I.getData();
}
-
- Mgr->getConstraintManager().print(this, Out, nl, sep);
-
+
+ Mgr.getConstraintManager().print(this, Out, nl, sep);
+
// Print checker-specific data.
- for (std::vector<Printer*>::iterator I = Mgr->Printers.begin(),
- E = Mgr->Printers.end(); I != E; ++I) {
+ for (std::vector<Printer*>::iterator I = Mgr.Printers.begin(),
+ E = Mgr.Printers.end(); I != E; ++I) {
(*I)->Print(Out, this, nl, sep);
}
}
@@ -219,23 +205,23 @@ void*
GRStateManager::FindGDMContext(void* K,
void* (*CreateContext)(llvm::BumpPtrAllocator&),
void (*DeleteContext)(void*)) {
-
+
std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
if (!p.first) {
p.first = CreateContext(Alloc);
p.second = DeleteContext;
}
-
+
return p.first;
}
const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
GRState::GenericDataMap M1 = St->getGDM();
GRState::GenericDataMap M2 = GDMFactory.Add(M1, Key, Data);
-
+
if (M1 == M2)
return St;
-
+
GRState NewSt = *St;
NewSt.GDM = M2;
return getPersistentState(NewSt);
@@ -254,14 +240,14 @@ class VISIBILITY_HIDDEN ScanReachableSymbols : public SubRegionMap::Visitor {
SymbolVisitor &visitor;
llvm::OwningPtr<SubRegionMap> SRM;
public:
-
+
ScanReachableSymbols(const GRState *st, SymbolVisitor& v)
: state(st), 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);
@@ -276,44 +262,44 @@ bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
return true;
}
-
+
bool ScanReachableSymbols::scan(SVal val) {
if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
return scan(X->getRegion());
if (SymbolRef Sym = val.getAsSymbol())
return visitor.VisitSymbol(Sym);
-
+
if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
return scan(*X);
-
+
return true;
}
-
+
bool ScanReachableSymbols::scan(const MemRegion *R) {
if (isa<MemSpaceRegion>(R) || 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->getSValAsScalarOrLoc(R)))
return false;
-
+
// Now look at the subregions.
if (!SRM.get())
SRM.reset(state->getStateManager().getStoreManager().getSubRegionMap(state));
-
+
return SRM->iterSubRegions(R, *this);
}
@@ -326,24 +312,24 @@ bool GRState::scanReachableSymbols(SVal val, SymbolVisitor& visitor) const {
// Queries.
//===----------------------------------------------------------------------===//
-bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
+bool GRStateManager::isEqual(const GRState* state, const Expr* Ex,
const llvm::APSInt& Y) {
-
+
SVal V = state->getSVal(Ex);
-
+
if (loc::ConcreteInt* X = dyn_cast<loc::ConcreteInt>(&V))
return X->getValue() == Y;
if (nonloc::ConcreteInt* X = dyn_cast<nonloc::ConcreteInt>(&V))
return X->getValue() == Y;
-
+
if (SymbolRef Sym = V.getAsSymbol())
return ConstraintMgr->isEqual(state, Sym, Y);
return false;
}
-
-bool GRStateManager::isEqual(const GRState* state, Expr* Ex, uint64_t x) {
+
+bool GRStateManager::isEqual(const GRState* state, const Expr* Ex, uint64_t x) {
return isEqual(state, Ex, getBasicVals().getValue(x, Ex->getType()));
}