Simplify 'Environment' to contain only one map from 'const Stmt*' to SVals, greatly simplifying the logic of the analyzer in many places. We now only distinguish between block-level expressions and subexpressions in Environment::RemoveDeadBindings and GRState pretty-printing.

llvm-svn: 80194
This commit is contained in:
Ted Kremenek 2009-08-27 01:39:13 +00:00
parent 81cb753298
commit 907a711f60
6 changed files with 204 additions and 306 deletions

View File

@ -26,10 +26,12 @@
namespace clang {
class AnalysisContext;
class EnvironmentManager;
class ValueManager;
class LiveVariables;
class Environment {
private:
friend class EnvironmentManager;
@ -38,47 +40,27 @@ private:
typedef llvm::ImmutableMap<const Stmt*,SVal> BindingsTy;
// Data.
BindingsTy SubExprBindings;
BindingsTy BlkExprBindings;
BindingsTy ExprBindings;
Environment(BindingsTy seb, BindingsTy beb)
: SubExprBindings(seb), BlkExprBindings(beb) {}
Environment(BindingsTy eb)
: ExprBindings(eb) {}
public:
public:
typedef BindingsTy::iterator iterator;
iterator begin() const { return ExprBindings.begin(); }
iterator end() const { return ExprBindings.end(); }
typedef BindingsTy::iterator seb_iterator;
seb_iterator seb_begin() const { return SubExprBindings.begin(); }
seb_iterator seb_end() const { return SubExprBindings.end(); }
typedef BindingsTy::iterator beb_iterator;
beb_iterator beb_begin() const { return BlkExprBindings.begin(); }
beb_iterator beb_end() const { return BlkExprBindings.end(); }
SVal LookupSubExpr(const Stmt* E) const {
const SVal* X = SubExprBindings.lookup(cast<Expr>(E));
return X ? *X : UnknownVal();
}
SVal LookupBlkExpr(const Stmt* E) const {
const SVal* X = BlkExprBindings.lookup(E);
return X ? *X : UnknownVal();
}
SVal LookupExpr(const Stmt* E) const {
const SVal* X = SubExprBindings.lookup(E);
if (X) return *X;
X = BlkExprBindings.lookup(E);
const SVal* X = ExprBindings.lookup(E);
return X ? *X : UnknownVal();
}
SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const;
SVal GetBlkExprSVal(const Stmt* Ex, ValueManager& ValMgr) const;
/// Profile - Profile the contents of an Environment object for use
/// in a FoldingSet.
static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
E->SubExprBindings.Profile(ID);
E->BlkExprBindings.Profile(ID);
E->ExprBindings.Profile(ID);
}
/// Profile - Used to profile the contents of this object for inclusion
@ -88,8 +70,7 @@ public:
}
bool operator==(const Environment& RHS) const {
return SubExprBindings == RHS.SubExprBindings &&
BlkExprBindings == RHS.BlkExprBindings;
return ExprBindings == RHS.ExprBindings;
}
};
@ -98,51 +79,20 @@ private:
typedef Environment::BindingsTy::Factory FactoryTy;
FactoryTy F;
public:
public:
EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
~EnvironmentManager() {}
/// RemoveBlkExpr - Return a new environment object with the same bindings as
/// the provided environment except with any bindings for the provided Stmt*
/// removed. This method only removes bindings for block-level expressions.
/// Using this method on a non-block level expression will return the
/// same environment object.
Environment RemoveBlkExpr(const Environment& Env, const Stmt* E) {
return Environment(Env.SubExprBindings, F.Remove(Env.BlkExprBindings, E));
}
Environment RemoveSubExpr(const Environment& Env, const Stmt* E) {
return Environment(F.Remove(Env.SubExprBindings, E), Env.BlkExprBindings);
}
Environment AddBlkExpr(const Environment& Env, const Stmt *E, SVal V) {
return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V));
}
Environment AddSubExpr(const Environment& Env, const Stmt *E, SVal V) {
return Environment(F.Add(Env.SubExprBindings, E, V), Env.BlkExprBindings);
}
/// RemoveSubExprBindings - Return a new environment object with
/// the same bindings as the provided environment except with all the
/// subexpression bindings removed.
Environment RemoveSubExprBindings(const Environment& Env) {
return Environment(F.GetEmptyMap(), Env.BlkExprBindings);
}
Environment getInitialEnvironment() {
return Environment(F.GetEmptyMap(), F.GetEmptyMap());
return Environment(F.GetEmptyMap());
}
Environment BindExpr(const Environment& Env, const Stmt* E, SVal V,
bool isBlkExpr, bool Invalidate);
Environment
RemoveDeadBindings(Environment Env, Stmt* Loc, SymbolReaper& SymReaper,
GRStateManager& StateMgr, const GRState *state,
llvm::SmallVectorImpl<const MemRegion*>& DRoots);
Environment BindExpr(Environment Env, const Stmt *S, SVal V,
bool Invalidate);
Environment RemoveDeadBindings(Environment Env, const Stmt *S,
SymbolReaper &SymReaper, const GRState *ST,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
};
} // end clang namespace

View File

@ -67,6 +67,15 @@ template <typename T> struct GRStateTrait {
class GRStateManager;
class GRStateContext : public std::pair<GRStateManager*, AnalysisContext*> {
public:
GRStateContext(GRStateManager *Mgr, AnalysisContext *ACtx)
: std::pair<GRStateManager*, AnalysisContext*>(Mgr, ACtx) {}
GRStateManager *getStateManager() const { return first; }
AnalysisContext *getAnalysisContext() const { return second; }
};
/// GRState - This class encapsulates the actual data values for
/// for a "state" in our symbolic value tracking. It is intended to be
/// used as a functional object; that is once it is created and made
@ -81,7 +90,7 @@ private:
friend class GRStateManager;
GRStateManager *Mgr;
GRStateContext StateCtx;
Environment Env;
Store St;
@ -92,9 +101,9 @@ public:
public:
/// This ctor is used when creating the first GRState object.
GRState(GRStateManager *mgr, const Environment& env, Store st,
GenericDataMap gdm)
: Mgr(mgr),
GRState(GRStateManager *mgr, AnalysisContext *actx, const Environment& env,
Store st, GenericDataMap gdm)
: StateCtx(mgr, actx),
Env(env),
St(st),
GDM(gdm) {}
@ -103,13 +112,21 @@ public:
/// in FoldingSetNode will also get copied.
GRState(const GRState& RHS)
: llvm::FoldingSetNode(),
Mgr(RHS.Mgr),
StateCtx(RHS.StateCtx),
Env(RHS.Env),
St(RHS.St),
GDM(RHS.GDM) {}
/// getStateManager - Return the GRStateManager associated with this state.
GRStateManager &getStateManager() const { return *Mgr; }
GRStateManager &getStateManager() const {
return *StateCtx.getStateManager();
}
/// getAnalysisContext - Return the AnalysisContext associated with this
/// state.
AnalysisContext &getAnalysisContext() const {
return *StateCtx.getAnalysisContext();
}
/// getEnvironment - Return the environment associated with this state.
/// The environment is the mapping from expressions to values.
@ -129,6 +146,7 @@ public:
/// Profile - Profile the contents of a GRState object for use
/// in a FoldingSet.
static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) {
// FIXME: Do we need to include the AnalysisContext in the profile?
V->Env.Profile(ID);
ID.AddPointer(V->St);
V->GDM.Profile(ID);
@ -147,16 +165,7 @@ public:
/// makeWithStore - Return a GRState with the same values as the current
/// state with the exception of using the specified Store.
const GRState *makeWithStore(Store store) const;
// Iterators.
typedef Environment::seb_iterator seb_iterator;
seb_iterator seb_begin() const { return Env.seb_begin(); }
seb_iterator seb_end() const { return Env.beb_end(); }
typedef Environment::beb_iterator beb_iterator;
beb_iterator beb_begin() const { return Env.beb_begin(); }
beb_iterator beb_end() const { return Env.beb_end(); }
BasicValueFactory &getBasicVals() const;
SymbolManager &getSymbolManager() const;
GRTransferFuncs &getTransferFuncs() const;
@ -216,16 +225,8 @@ public:
const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL,
SVal V) const;
const GRState *bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr,
bool Invalidate) const;
const GRState *bindExpr(const Stmt* Ex, SVal V, CFG &cfg,
bool Invalidate = true) const;
const GRState *bindBlkExpr(const Stmt *Ex, SVal V) const {
return bindExpr(Ex, V, true, false);
}
const GRState *bindExpr(const Stmt *S, SVal V, bool Invalidate = true) const;
const GRState *bindDecl(const VarDecl *VD, const LocationContext *LC,
SVal V) const;
@ -259,8 +260,6 @@ public:
SVal getSVal(const Stmt* Ex) const;
SVal getBlkExprSVal(const Stmt* Ex) const;
SVal getSValAsScalarOrLoc(const Stmt *Ex) const;
SVal getSVal(Loc LV, QualType T = QualType()) const;
@ -475,12 +474,6 @@ public:
const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
SymbolReaper& SymReaper);
const GRState* RemoveSubExprBindings(const GRState* St) {
GRState NewSt = *St;
NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
return getPersistentState(NewSt);
}
public:
SVal ArrayToPointer(Loc Array) {
@ -583,36 +576,36 @@ public:
inline const VarRegion* GRState::getRegion(const VarDecl *D,
const LocationContext *LC) const {
return Mgr->getRegionManager().getVarRegion(D, LC);
return getStateManager().getRegionManager().getVarRegion(D, LC);
}
inline const GRState *GRState::assume(SVal Cond, bool Assumption) const {
return Mgr->ConstraintMgr->Assume(this, Cond, Assumption);
return getStateManager().ConstraintMgr->Assume(this, Cond, Assumption);
}
inline const GRState *GRState::assumeInBound(SVal Idx, SVal UpperBound,
bool Assumption) const {
return Mgr->ConstraintMgr->AssumeInBound(this, Idx, UpperBound, Assumption);
return getStateManager().ConstraintMgr->AssumeInBound(this, Idx, UpperBound, Assumption);
}
inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
SVal V) const {
return Mgr->StoreMgr->BindCompoundLiteral(this, CL, V);
return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, V);
}
inline const GRState *GRState::bindDecl(const VarDecl* VD,
const LocationContext *LC,
SVal IVal) const {
return Mgr->StoreMgr->BindDecl(this, VD, LC, IVal);
return getStateManager().StoreMgr->BindDecl(this, VD, LC, IVal);
}
inline const GRState *GRState::bindDeclWithNoInit(const VarDecl* VD,
const LocationContext *LC) const {
return Mgr->StoreMgr->BindDeclWithNoInit(this, VD, LC);
return getStateManager().StoreMgr->BindDeclWithNoInit(this, VD, LC);
}
inline const GRState *GRState::bindLoc(Loc LV, SVal V) const {
return Mgr->StoreMgr->Bind(this, LV, V);
return getStateManager().StoreMgr->Bind(this, LV, V);
}
inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
@ -621,39 +614,35 @@ inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
inline SVal GRState::getLValue(const VarDecl* VD,
const LocationContext *LC) const {
return Mgr->StoreMgr->getLValueVar(this, VD, LC);
return getStateManager().StoreMgr->getLValueVar(this, VD, LC);
}
inline SVal GRState::getLValue(const StringLiteral *literal) const {
return Mgr->StoreMgr->getLValueString(this, literal);
return getStateManager().StoreMgr->getLValueString(this, literal);
}
inline SVal GRState::getLValue(const CompoundLiteralExpr *literal) const {
return Mgr->StoreMgr->getLValueCompoundLiteral(this, literal);
return getStateManager().StoreMgr->getLValueCompoundLiteral(this, literal);
}
inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
return Mgr->StoreMgr->getLValueIvar(this, D, Base);
return getStateManager().StoreMgr->getLValueIvar(this, D, Base);
}
inline SVal GRState::getLValue(SVal Base, const FieldDecl* D) const {
return Mgr->StoreMgr->getLValueField(this, Base, D);
return getStateManager().StoreMgr->getLValueField(this, Base, D);
}
inline SVal GRState::getLValue(QualType ElementType, SVal Base, SVal Idx) const{
return Mgr->StoreMgr->getLValueElement(this, ElementType, Base, Idx);
return getStateManager().StoreMgr->getLValueElement(this, ElementType, Base, Idx);
}
inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const {
return Mgr->getSymVal(this, sym);
return getStateManager().getSymVal(this, sym);
}
inline SVal GRState::getSVal(const Stmt* Ex) const {
return Env.GetSVal(Ex, Mgr->ValueMgr);
}
inline SVal GRState::getBlkExprSVal(const Stmt* Ex) const {
return Env.GetBlkExprSVal(Ex, Mgr->ValueMgr);
return Env.GetSVal(Ex, getStateManager().ValueMgr);
}
inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
@ -667,62 +656,62 @@ inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
}
inline SVal GRState::getSVal(Loc LV, QualType T) const {
return Mgr->StoreMgr->Retrieve(this, LV, T).getSVal();
return getStateManager().StoreMgr->Retrieve(this, LV, T).getSVal();
}
inline SVal GRState::getSVal(const MemRegion* R) const {
return Mgr->StoreMgr->Retrieve(this, loc::MemRegionVal(R)).getSVal();
return getStateManager().StoreMgr->Retrieve(this, loc::MemRegionVal(R)).getSVal();
}
inline BasicValueFactory &GRState::getBasicVals() const {
return Mgr->getBasicVals();
return getStateManager().getBasicVals();
}
inline SymbolManager &GRState::getSymbolManager() const {
return Mgr->getSymbolManager();
return getStateManager().getSymbolManager();
}
inline GRTransferFuncs &GRState::getTransferFuncs() const {
return Mgr->getTransferFuncs();
return getStateManager().getTransferFuncs();
}
template<typename T>
const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const {
return Mgr->add<T>(this, K, get_context<T>());
return getStateManager().add<T>(this, K, get_context<T>());
}
template <typename T>
typename GRStateTrait<T>::context_type GRState::get_context() const {
return Mgr->get_context<T>();
return getStateManager().get_context<T>();
}
template<typename T>
const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const {
return Mgr->remove<T>(this, K, get_context<T>());
return getStateManager().remove<T>(this, K, get_context<T>());
}
template<typename T>
const GRState *GRState::remove(typename GRStateTrait<T>::key_type K,
typename GRStateTrait<T>::context_type C) const {
return Mgr->remove<T>(this, K, C);
return getStateManager().remove<T>(this, K, C);
}
template<typename T>
const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const {
return Mgr->set<T>(this, D);
return getStateManager().set<T>(this, D);
}
template<typename T>
const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
typename GRStateTrait<T>::value_type E) const {
return Mgr->set<T>(this, K, E, get_context<T>());
return getStateManager().set<T>(this, K, E, get_context<T>());
}
template<typename T>
const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
typename GRStateTrait<T>::value_type E,
typename GRStateTrait<T>::context_type C) const {
return Mgr->set<T>(this, K, E, C);
return getStateManager().set<T>(this, K, E, C);
}
template <typename CB>

View File

@ -2900,7 +2900,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
unsigned Count = Builder.getCurrentBlockCount();
ValueManager &ValMgr = Eng.getValueManager();
SVal X = ValMgr.getConjuredSymbolVal(Ex, T, Count);
state = state->bindExpr(Ex, X, Pred->getCFG(), false);
state = state->bindExpr(Ex, X, false);
}
break;
@ -2911,14 +2911,14 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
assert (arg_end >= arg_beg);
assert (idx < (unsigned) (arg_end - arg_beg));
SVal V = state->getSValAsScalarOrLoc(*(arg_beg+idx));
state = state->bindExpr(Ex, V, Pred->getCFG(), false);
state = state->bindExpr(Ex, V, false);
break;
}
case RetEffect::ReceiverAlias: {
assert (Receiver);
SVal V = state->getSValAsScalarOrLoc(Receiver);
state = state->bindExpr(Ex, V, Pred->getCFG(), false);
state = state->bindExpr(Ex, V, false);
break;
}
@ -2930,7 +2930,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
QualType RetT = GetReturnType(Ex, ValMgr.getContext());
state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
RetT));
state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), Pred->getCFG(), false);
state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), false);
// FIXME: Add a flag to the checker where allocations are assumed to
// *not fail.
@ -2953,7 +2953,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
QualType RetT = GetReturnType(Ex, ValMgr.getContext());
state = state->set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(),
RetT));
state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), Pred->getCFG(), false);
state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), false);
break;
}
}

View File

@ -68,42 +68,18 @@ SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
return LookupExpr(E);
}
SVal Environment::GetBlkExprSVal(const Stmt *E, ValueManager& ValMgr) const {
while (1) {
switch (E->getStmtClass()) {
case Stmt::ParenExprClass:
E = cast<ParenExpr>(E)->getSubExpr();
continue;
case Stmt::CharacterLiteralClass: {
const CharacterLiteral* C = cast<CharacterLiteral>(E);
return ValMgr.makeIntVal(C->getValue(), C->getType());
}
case Stmt::IntegerLiteralClass: {
return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
}
default:
return LookupBlkExpr(E);
}
}
}
Environment EnvironmentManager::BindExpr(const Environment& Env, const Stmt* E,
SVal V, bool isBlkExpr,
bool Invalidate) {
assert (E);
Environment EnvironmentManager::BindExpr(Environment Env, const Stmt *S,
SVal V, bool Invalidate) {
assert(S);
if (V.isUnknown()) {
if (Invalidate)
return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
return Environment(F.Remove(Env.ExprBindings, S));
else
return Env;
}
return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
return Environment(F.Add(Env.ExprBindings, S, V));
}
namespace {
@ -124,23 +100,34 @@ public:
// - Mark the region in DRoots if the binding is a loc::MemRegionVal.
Environment
EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
SymbolReaper& SymReaper,
GRStateManager& StateMgr,
const GRState *state,
llvm::SmallVectorImpl<const MemRegion*>& DRoots) {
EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
SymbolReaper &SymReaper,
const GRState *ST,
llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
CFG &C = *ST->getAnalysisContext().getCFG();
// We construct a new Environment object entirely, as this is cheaper than
// individually removing all the subexpression bindings (which will greatly
// outnumber block-level expression bindings).
Environment NewEnv = getInitialEnvironment();
// Drop bindings for subexpressions.
Env = RemoveSubExprBindings(Env);
// Iterate over the block-expr bindings.
for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end();
for (Environment::iterator I = Env.begin(), E = Env.end();
I != E; ++I) {
const Stmt *BlkExpr = I.getKey();
if (SymReaper.isLive(Loc, BlkExpr)) {
SVal X = I.getData();
// Not a block-level expression?
if (!C.isBlkExpr(BlkExpr))
continue;
const SVal &X = I.getData();
if (SymReaper.isLive(S, BlkExpr)) {
// Copy the binding to the new map.
NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
// If the block expr's value is a memory region, then mark that region.
if (isa<loc::MemRegionVal>(X)) {
const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
@ -151,28 +138,23 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
// We only add one level super region for now.
// FIXME: maybe multiple level of super regions should be added.
if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
if (const SubRegion *SR = dyn_cast<SubRegion>(R))
DRoots.push_back(SR->getSuperRegion());
}
}
// Mark all symbols in the block expr's value live.
MarkLiveCallback cb(SymReaper);
state->scanReachableSymbols(X, cb);
} else {
// The block expr is dead.
SVal X = I.getData();
// Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
// beginning of itself, but we need its UndefinedVal to determine its
// SVal.
if (X.isUndef() && cast<UndefinedVal>(X).getData())
continue;
Env = RemoveBlkExpr(Env, BlkExpr);
ST->scanReachableSymbols(X, cb);
continue;
}
// Otherwise the expression is dead with a couple exceptions.
// Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
// beginning of itself, but we need its UndefinedVal to determine its
// SVal.
if (X.isUndef() && cast<UndefinedVal>(X).getData())
NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
}
return Env;
return NewEnv;
}

View File

@ -341,8 +341,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
}
else if (B->getOpcode() == BinaryOperator::Comma) {
const GRState* state = GetState(Pred);
MakeNode(Dst, B, Pred, state->bindExpr(B, state->getSVal(B->getRHS()),
Pred->getCFG()));
MakeNode(Dst, B, Pred, state->bindExpr(B, state->getSVal(B->getRHS())));
break;
}
@ -459,8 +458,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
if (Expr* LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
const GRState* state = GetState(Pred);
MakeNode(Dst, SE, Pred, state->bindExpr(SE, state->getSVal(LastExpr),
Pred->getCFG()));
MakeNode(Dst, SE, Pred, state->bindExpr(SE, state->getSVal(LastExpr)));
}
else
Dst.Add(Pred);
@ -543,7 +541,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
case Stmt::StringLiteralClass: {
const GRState* state = GetState(Pred);
SVal V = state->getLValue(cast<StringLiteral>(Ex));
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()));
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V));
return;
}
@ -612,7 +610,7 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
(Op == BinaryOperator::LOr && !branchTaken)
? B->getRHS() : B->getLHS();
return state->bindBlkExpr(B, UndefinedVal(Ex));
return state->bindExpr(B, UndefinedVal(Ex));
}
case Stmt::ConditionalOperatorClass: { // ?:
@ -629,7 +627,7 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
else
Ex = C->getRHS();
return state->bindBlkExpr(C, UndefinedVal(Ex));
return state->bindExpr(C, UndefinedVal(Ex));
}
case Stmt::ChooseExprClass: { // ?:
@ -637,7 +635,7 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
ChooseExpr* C = cast<ChooseExpr>(Terminator);
Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
return state->bindBlkExpr(C, UndefinedVal(Ex));
return state->bindExpr(C, UndefinedVal(Ex));
}
}
}
@ -684,10 +682,6 @@ static SVal RecoverCastedSymbol(GRStateManager& StateMgr, const GRState* state,
void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
GRBranchNodeBuilder& builder) {
// Remove old bindings for subexpressions.
const GRState* PrevState =
StateMgr.RemoveSubExprBindings(builder.getState());
// Check for NULL conditions; e.g. "for(;;)"
if (!Condition) {
builder.markInfeasible(false);
@ -697,7 +691,8 @@ void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
Condition->getLocStart(),
"Error evaluating branch");
const GRState* PrevState = builder.getState();
SVal V = PrevState->getSVal(Condition);
switch (V.getBaseKind()) {
@ -808,16 +803,16 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
assert (Ex == CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex));
const GRState* state = GetState(Pred);
SVal X = state->getBlkExprSVal(Ex);
SVal X = state->getSVal(Ex);
assert (X.isUndef());
Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
assert(SE);
X = state->getBlkExprSVal(SE);
X = state->getSVal(SE);
// Make sure that we invalidate the previous binding.
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, X, true, true));
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, X, true));
}
/// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
@ -918,7 +913,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
assert(B == CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(B));
const GRState* state = GetState(Pred);
SVal X = state->getBlkExprSVal(B);
SVal X = state->getSVal(B);
assert(X.isUndef());
Expr* Ex = (Expr*) cast<UndefinedVal>(X).getData();
@ -927,12 +922,12 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
if (Ex == B->getRHS()) {
X = state->getBlkExprSVal(Ex);
X = state->getSVal(Ex);
// Handle undefined values.
if (X.isUndef()) {
MakeNode(Dst, B, Pred, state->bindBlkExpr(B, X));
MakeNode(Dst, B, Pred, state->bindExpr(B, X));
return;
}
@ -944,11 +939,11 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
// the payoff is not likely to be large. Instead, we do eager evaluation.
if (const GRState *newState = state->assume(X, true))
MakeNode(Dst, B, Pred,
newState->bindBlkExpr(B, ValMgr.makeIntVal(1U, B->getType())));
newState->bindExpr(B, ValMgr.makeIntVal(1U, B->getType())));
if (const GRState *newState = state->assume(X, false))
MakeNode(Dst, B, Pred,
newState->bindBlkExpr(B, ValMgr.makeIntVal(0U, B->getType())));
newState->bindExpr(B, ValMgr.makeIntVal(0U, B->getType())));
}
else {
// We took the LHS expression. Depending on whether we are '&&' or
@ -956,7 +951,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
// the short-circuiting.
X = ValMgr.makeIntVal(B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U,
B->getType());
MakeNode(Dst, B, Pred, state->bindBlkExpr(B, X));
MakeNode(Dst, B, Pred, state->bindExpr(B, X));
}
}
@ -976,7 +971,7 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
SVal V = state->getLValue(VD, Pred->getLocationContext());
if (asLValue)
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()),
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V),
ProgramPoint::PostLValueKind);
else
EvalLoad(Dst, Ex, Pred, state, V);
@ -986,13 +981,13 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
assert(!asLValue && "EnumConstantDecl does not have lvalue.");
SVal V = ValMgr.makeIntVal(ED->getInitVal());
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()));
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V));
return;
} else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
assert(asLValue);
SVal V = ValMgr.getFunctionPointer(FD);
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()),
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V),
ProgramPoint::PostLValueKind);
return;
}
@ -1030,7 +1025,7 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
state->getSVal(Idx));
if (asLValue)
MakeNode(Dst, A, *I2, state->bindExpr(A, V, Pred->getCFG()),
MakeNode(Dst, A, *I2, state->bindExpr(A, V),
ProgramPoint::PostLValueKind);
else
EvalLoad(Dst, A, *I2, state, V);
@ -1062,7 +1057,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
SVal L = state->getLValue(state->getSVal(Base), Field);
if (asLValue)
MakeNode(Dst, M, *I, state->bindExpr(M, L, Pred->getCFG()),
MakeNode(Dst, M, *I, state->bindExpr(M, L),
ProgramPoint::PostLValueKind);
else
EvalLoad(Dst, M, *I, state, L);
@ -1146,7 +1141,7 @@ void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
if (location.isUnknown()) {
// This is important. We must nuke the old binding.
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, UnknownVal(), Pred->getCFG()),
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, UnknownVal()),
K, tag);
}
else {
@ -1164,7 +1159,7 @@ void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
// V = EvalCast(V, Ex->getType());
//}
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()), K, tag);
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V), K, tag);
}
}
@ -1387,16 +1382,14 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet& Dst,
ExplodedNode *predNew = *I2;
const GRState *stateNew = predNew->getState();
SVal Res = Engine.getValueManager().makeTruthVal(true, CE->getType());
Engine.MakeNode(Dst, CE, predNew, stateNew->bindExpr(CE, Res,
Pred->getCFG()));
Engine.MakeNode(Dst, CE, predNew, stateNew->bindExpr(CE, Res));
}
}
// Were they not equal?
if (const GRState *stateNotEqual = stateLoad->assume(Cmp, false)) {
SVal Res = Engine.getValueManager().makeTruthVal(false, CE->getType());
Engine.MakeNode(Dst, CE, N, stateNotEqual->bindExpr(CE, Res,
Pred->getCFG()));
Engine.MakeNode(Dst, CE, N, stateNotEqual->bindExpr(CE, Res));
}
}
@ -1611,7 +1604,7 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, ExplodedNode* Pred,
// For __builtin_expect, just return the value of the subexpression.
assert (CE->arg_begin() != CE->arg_end());
SVal X = state->getSVal(*(CE->arg_begin()));
MakeNode(Dst, CE, *DI, state->bindExpr(CE, X, Pred->getCFG()));
MakeNode(Dst, CE, *DI, state->bindExpr(CE, X));
continue;
}
@ -1626,9 +1619,7 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, ExplodedNode* Pred,
// cannot represent values like symbol*8.
SVal Extent = state->getSVal(*(CE->arg_begin()));
state = getStoreManager().setExtent(state, R, Extent);
MakeNode(Dst, CE, *DI, state->bindExpr(CE, loc::MemRegionVal(R),
Pred->getCFG()));
MakeNode(Dst, CE, *DI, state->bindExpr(CE, loc::MemRegionVal(R)));
continue;
}
@ -1701,8 +1692,7 @@ void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
// First assume that the condition is true.
if (const GRState *stateTrue = state->assume(V, true)) {
stateTrue = stateTrue->bindExpr(Ex,
ValMgr.makeIntVal(1U, Ex->getType()),
Pred->getCFG());
ValMgr.makeIntVal(1U, Ex->getType()));
Dst.Add(Builder->generateNode(PostStmtCustom(Ex,
&EagerlyAssumeTag, Pred->getLocationContext()),
stateTrue, Pred));
@ -1711,8 +1701,7 @@ void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
// Next, assume that the condition is false.
if (const GRState *stateFalse = state->assume(V, false)) {
stateFalse = stateFalse->bindExpr(Ex,
ValMgr.makeIntVal(0U, Ex->getType()),
Pred->getCFG());
ValMgr.makeIntVal(0U, Ex->getType()));
Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag,
Pred->getLocationContext()),
stateFalse, Pred));
@ -1741,7 +1730,7 @@ void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex,
SVal location = state->getLValue(Ex->getDecl(), BaseVal);
if (asLValue)
MakeNode(Dst, Ex, *I, state->bindExpr(Ex, location, Pred->getCFG()));
MakeNode(Dst, Ex, *I, state->bindExpr(Ex, location));
else
EvalLoad(Dst, Ex, *I, state, location);
}
@ -1817,11 +1806,11 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
// Handle the case where the container still has elements.
SVal TrueV = ValMgr.makeTruthVal(1);
const GRState *hasElems = state->bindExpr(S, TrueV, Pred->getCFG());
const GRState *hasElems = state->bindExpr(S, TrueV);
// Handle the case where the container has no elements.
SVal FalseV = ValMgr.makeTruthVal(0);
const GRState *noElems = state->bindExpr(S, FalseV, Pred->getCFG());
const GRState *noElems = state->bindExpr(S, FalseV);
if (loc::MemRegionVal* MV = dyn_cast<loc::MemRegionVal>(&ElementV))
if (const TypedRegion* R = dyn_cast<TypedRegion>(MV->getRegion())) {
@ -1973,7 +1962,7 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
// of this case unless we have *a lot* more knowledge.
//
SVal V = ValMgr.makeZeroVal(ME->getType());
MakeNode(Dst, ME, Pred, StNull->bindExpr(ME, V, Pred->getCFG()));
MakeNode(Dst, ME, Pred, StNull->bindExpr(ME, V));
return;
}
}
@ -2110,7 +2099,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred, Exploded
const GRState* state = GetState(N);
SVal V = state->getSVal(Ex);
const SValuator::CastResult &Res = SVator.EvalCast(V, state, T, ExTy);
state = Res.getState()->bindExpr(CastE, Res.getSVal(), Pred->getCFG());
state = Res.getState()->bindExpr(CastE, Res.getSVal());
MakeNode(Dst, CastE, N, state);
}
}
@ -2129,10 +2118,9 @@ void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
state = state->bindCompoundLiteral(CL, ILV);
if (asLValue)
MakeNode(Dst, CL, *I, state->bindExpr(CL, state->getLValue(CL),
Pred->getCFG()));
MakeNode(Dst, CL, *I, state->bindExpr(CL, state->getLValue(CL)));
else
MakeNode(Dst, CL, *I, state->bindExpr(CL, ILV, Pred->getCFG()));
MakeNode(Dst, CL, *I, state->bindExpr(CL, ILV));
}
}
@ -2256,7 +2244,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
// e.g: static int* myArray[] = {};
if (NumInitElements == 0) {
SVal V = ValMgr.makeCompoundVal(T, StartVals);
MakeNode(Dst, E, Pred, state->bindExpr(E, V, Pred->getCFG()));
MakeNode(Dst, E, Pred, state->bindExpr(E, V));
return;
}
@ -2291,7 +2279,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
SVal V = ValMgr.makeCompoundVal(T, NewVals);
// Make final state and node.
MakeNode(Dst, E, *NI, state->bindExpr(E, V, (*NI)->getCFG()));
MakeNode(Dst, E, *NI, state->bindExpr(E, V));
}
else {
// Still some initializer values to go. Push them onto the worklist.
@ -2310,7 +2298,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
Visit(Init, Pred, Tmp);
for (ExplodedNodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I != EI; ++I) {
state = GetState(*I);
MakeNode(Dst, E, *I, state->bindExpr(E, state->getSVal(Init), Pred->getCFG()));
MakeNode(Dst, E, *I, state->bindExpr(E, state->getSVal(Init)));
}
return;
}
@ -2351,8 +2339,7 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
amt = getContext().getTypeAlign(T) / 8;
MakeNode(Dst, Ex, Pred,
GetState(Pred)->bindExpr(Ex, ValMgr.makeIntVal(amt, Ex->getType()),
Pred->getCFG()));
GetState(Pred)->bindExpr(Ex, ValMgr.makeIntVal(amt, Ex->getType())));
}
@ -2376,7 +2363,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
SVal location = state->getSVal(Ex);
if (asLValue)
MakeNode(Dst, U, *I, state->bindExpr(U, location, (*I)->getCFG()),
MakeNode(Dst, U, *I, state->bindExpr(U, location),
ProgramPoint::PostLValueKind);
else
EvalLoad(Dst, U, *I, state, location);
@ -2403,7 +2390,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
// For all other types, UnaryOperator::Real is an identity operation.
assert (U->getType() == Ex->getType());
const GRState* state = GetState(*I);
MakeNode(Dst, U, *I, state->bindExpr(U, state->getSVal(Ex), (*I)->getCFG()));
MakeNode(Dst, U, *I, state->bindExpr(U, state->getSVal(Ex)));
}
return;
@ -2427,7 +2414,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
assert (Ex->getType()->isIntegerType());
const GRState* state = GetState(*I);
SVal X = ValMgr.makeZeroVal(Ex->getType());
MakeNode(Dst, U, *I, state->bindExpr(U, X, (*I)->getCFG()));
MakeNode(Dst, U, *I, state->bindExpr(U, X));
}
return;
@ -2452,7 +2439,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* state = GetState(*I);
MakeNode(Dst, U, *I, state->bindExpr(U, state->getSVal(Ex), (*I)->getCFG()));
MakeNode(Dst, U, *I, state->bindExpr(U, state->getSVal(Ex)));
}
return;
@ -2468,7 +2455,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* state = GetState(*I);
SVal V = state->getSVal(Ex);
state = state->bindExpr(U, V, (*I)->getCFG());
state = state->bindExpr(U, V);
MakeNode(Dst, U, *I, state);
}
@ -2491,7 +2478,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
SVal V = state->getSVal(Ex);
if (V.isUnknownOrUndef()) {
MakeNode(Dst, U, *I, state->bindExpr(U, V, (*I)->getCFG()));
MakeNode(Dst, U, *I, state->bindExpr(U, V));
continue;
}
@ -2513,13 +2500,12 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
case UnaryOperator::Not:
// FIXME: Do we need to handle promotions?
state = state->bindExpr(U, EvalComplement(cast<NonLoc>(V)),
(*I)->getCFG());
state = state->bindExpr(U, EvalComplement(cast<NonLoc>(V)));
break;
case UnaryOperator::Minus:
// FIXME: Do we need to handle promotions?
state = state->bindExpr(U, EvalMinus(cast<NonLoc>(V)), (*I)->getCFG());
state = state->bindExpr(U, EvalMinus(cast<NonLoc>(V)));
break;
case UnaryOperator::LNot:
@ -2541,7 +2527,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
U->getType());
}
state = state->bindExpr(U, Result, (*I)->getCFG());
state = state->bindExpr(U, Result);
break;
}
@ -2576,7 +2562,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
// Propagate unknown and undefined values.
if (V2.isUnknownOrUndef()) {
MakeNode(Dst, U, *I2, state->bindExpr(U, V2, (*I2)->getCFG()));
MakeNode(Dst, U, *I2, state->bindExpr(U, V2));
continue;
}
@ -2622,7 +2608,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
}
}
state = state->bindExpr(U, U->isPostfix() ? V2 : Result, (*I2)->getCFG());
state = state->bindExpr(U, U->isPostfix() ? V2 : Result);
// Perform the store.
EvalStore(Dst, U, *I2, state, V1, Result);
@ -2846,7 +2832,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Simulate the effects of a "store": bind the value of the RHS
// to the L-Value represented by the LHS.
EvalStore(Dst, B, LHS, *I2, state->bindExpr(B, RightV, (*I2)->getCFG()),
EvalStore(Dst, B, LHS, *I2, state->bindExpr(B, RightV),
LeftV, RightV);
continue;
}
@ -2889,7 +2875,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// The operands were *not* undefined, but the result is undefined.
// This is a special node that should be flagged as an error.
if (ExplodedNode* UndefNode = Builder->generateNode(B, state, *I2)) {
if (ExplodedNode* UndefNode = Builder->generateNode(B, state, *I2)){
UndefNode->markAsSink();
UndefResults.insert(UndefNode);
}
@ -2899,7 +2885,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Otherwise, create a new node.
MakeNode(Dst, B, *I2, state->bindExpr(B, Result, (*I2)->getCFG()));
MakeNode(Dst, B, *I2, state->bindExpr(B, Result));
continue;
}
}
@ -2947,15 +2933,15 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Propagate undefined values (left-side).
if (V.isUndef()) {
EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, V, (*I3)->getCFG()),
EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, V),
location, V);
continue;
}
// Propagate unknown values (left and right-side).
if (RightV.isUnknown() || V.isUnknown()) {
EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, UnknownVal(),
(*I3)->getCFG()), location, UnknownVal());
EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, UnknownVal()),
location, UnknownVal());
continue;
}
@ -2982,8 +2968,8 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Evaluate operands and promote to result type.
if (RightV.isUndef()) {
// Propagate undefined values (right-side).
EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, RightV, (*I3)->getCFG()),
location, RightV);
EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, RightV), location,
RightV);
continue;
}
@ -3028,7 +3014,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
llvm::tie(state, LHSVal) = SVator.EvalCast(Result, state, LTy, CTy);
}
EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, Result, (*I3)->getCFG()),
EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, Result),
location, LHSVal);
}
}

View File

@ -46,7 +46,7 @@ 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.
@ -58,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 {
@ -76,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);
}
@ -85,38 +85,22 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
}
const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr,
bool Invalidate) const {
const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, bool Invalidate) const {
Environment NewEnv = Mgr->EnvMgr.BindExpr(Env, Ex, V, isBlkExpr, Invalidate);
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, CFG &cfg,
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 = cfg.isBlkExpr(Ex);
if (!isBlkExpr)
return this;
}
return bindExpr(Ex, V, isBlkExpr, Invalidate);
return getStateManager().getPersistentState(NewSt);
}
const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {
GRState State(this, EnvMgr.getInitialEnvironment(),
GRState State(this, InitLoc->getAnalysisContext(),
EnvMgr.getInitialEnvironment(),
StoreMgr->getInitialStore(InitLoc),
GDMFactory.GetEmptyMap());
@ -141,7 +125,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);
}
//===----------------------------------------------------------------------===//
@ -151,12 +135,17 @@ const GRState* GRState::makeWithStore(Store store) const {
void GRState::print(llvm::raw_ostream& Out, const char* nl,
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;
@ -172,8 +161,10 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
// 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;
@ -187,11 +178,11 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
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);
}
}