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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80194 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 32ac27f..9216e1e 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -2900,7 +2900,7 @@
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 @@
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 @@
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 @@
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 9d8e09c..98cd7d8 100644
--- a/lib/Analysis/Environment.cpp
+++ b/lib/Analysis/Environment.cpp
@@ -68,42 +68,18 @@
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 @@
// - 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) {
- // Drop bindings for subexpressions.
- Env = RemoveSubExprBindings(Env);
-
+ 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();
+
// 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 @@
// 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 600c52c..41caeaf 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -341,8 +341,7 @@
}
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 @@
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 @@
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 @@
(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 @@
else
Ex = C->getRHS();
- return state->bindBlkExpr(C, UndefinedVal(Ex));
+ return state->bindExpr(C, UndefinedVal(Ex));
}
case Stmt::ChooseExprClass: { // ?:
@@ -637,7 +635,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
U->getType());
}
- state = state->bindExpr(U, Result, (*I)->getCFG());
+ state = state->bindExpr(U, Result);
break;
}
@@ -2576,7 +2562,7 @@
// 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 @@
}
}
- 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
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);
}
}
diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp
index 862bd5f..7bef351 100644
--- a/lib/Analysis/GRState.cpp
+++ b/lib/Analysis/GRState.cpp
@@ -46,7 +46,7 @@
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 @@
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 @@
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 @@
}
-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* GRState::makeWithStore(Store store) const {
GRState NewSt = *this;
NewSt.St = store;
- return Mgr->getPersistentState(NewSt);
+ return getStateManager().getPersistentState(NewSt);
}
//===----------------------------------------------------------------------===//
@@ -151,12 +135,17 @@
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 @@
// 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 @@
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);
}
}