diff options
Diffstat (limited to 'lib/Analysis/GRState.cpp')
-rw-r--r-- | lib/Analysis/GRState.cpp | 158 |
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())); } |