aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/PathSensitive/Environment.h88
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h119
-rw-r--r--lib/Analysis/CFRefCount.cpp10
-rw-r--r--lib/Analysis/Environment.cpp98
-rw-r--r--lib/Analysis/GRExprEngine.cpp136
-rw-r--r--lib/Analysis/GRState.cpp59
6 files changed, 204 insertions, 306 deletions
diff --git a/include/clang/Analysis/PathSensitive/Environment.h b/include/clang/Analysis/PathSensitive/Environment.h
index 6f8a126427..f4d36c3550 100644
--- a/include/clang/Analysis/PathSensitive/Environment.h
+++ b/include/clang/Analysis/PathSensitive/Environment.h
@@ -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
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index 7425d1f4bc..94ef54b731 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -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>
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 32ac27f258..9216e1ea01 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -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;
}
}
diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp
index 9d8e09c704..98cd7d8168 100644
--- a/lib/Analysis/Environment.cpp
+++ b/lib/Analysis/Environment.cpp
@@ -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;
}
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 600c52c5b0..41caeaf68a 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -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());
+ con