aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp89
1 files changed, 48 insertions, 41 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index dba1ce10bd..70142c8fc1 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -945,11 +945,9 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
const CFGBlock *DstT,
const CFGBlock *DstF) {
- BranchNodeBuilder builder(BldCtx, Pred, DstT, DstF);
-
// Check for NULL conditions; e.g. "for(;;)"
if (!Condition) {
- BranchNodeBuilder NullCondBldr(BldCtx, Pred, DstT, DstF);
+ BranchNodeBuilder NullCondBldr(Pred, BldCtx, DstT, DstF);
NullCondBldr.markInfeasible(false);
Engine.enqueue(NullCondBldr);
return;
@@ -959,27 +957,36 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
Condition->getLocStart(),
"Error evaluating branch");
- //TODO: This should take the NodeBuiolder.
- getCheckerManager().runCheckersForBranchCondition(Condition, builder,
+ NodeBuilder CheckerBldr(Pred, BldCtx);
+ getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
*this);
- const ProgramState *PrevState = builder.getState();
- SVal X = PrevState->getSVal(Condition);
-
- if (X.isUnknownOrUndef()) {
- // Give it a chance to recover from unknown.
- if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
- if (Ex->getType()->isIntegerType()) {
- // Try to recover some path-sensitivity. Right now casts of symbolic
- // integers that promote their values are currently not tracked well.
- // If 'Condition' is such an expression, try and recover the
- // underlying value and use that instead.
- SVal recovered = RecoverCastedSymbol(getStateManager(),
- builder.getState(), Condition,
- getContext());
-
- if (!recovered.isUnknown()) {
- X = recovered;
+ for (NodeBuilder::iterator I = CheckerBldr.results_begin(),
+ E = CheckerBldr.results_end(); E != I; ++I) {
+ ExplodedNode *PredI = *I;
+
+ if (PredI->isSink())
+ continue;
+
+ BranchNodeBuilder builder(PredI, BldCtx, DstT, DstF);
+ const ProgramState *PrevState = builder.getState();
+ SVal X = PrevState->getSVal(Condition);
+
+ if (X.isUnknownOrUndef()) {
+ // Give it a chance to recover from unknown.
+ if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
+ if (Ex->getType()->isIntegerType()) {
+ // Try to recover some path-sensitivity. Right now casts of symbolic
+ // integers that promote their values are currently not tracked well.
+ // If 'Condition' is such an expression, try and recover the
+ // underlying value and use that instead.
+ SVal recovered = RecoverCastedSymbol(getStateManager(),
+ PrevState, Condition,
+ getContext());
+
+ if (!recovered.isUnknown()) {
+ X = recovered;
+ }
}
}
}
@@ -989,30 +996,30 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
builder.generateNode(MarkBranch(PrevState, Term, false), false);
// Enqueue the results into the work list.
Engine.enqueue(builder);
- return;
+ continue;
}
- }
- DefinedSVal V = cast<DefinedSVal>(X);
+ DefinedSVal V = cast<DefinedSVal>(X);
- // Process the true branch.
- if (builder.isFeasible(true)) {
- if (const ProgramState *state = PrevState->assume(V, true))
- builder.generateNode(MarkBranch(state, Term, true), true);
- else
- builder.markInfeasible(true);
- }
+ // Process the true branch.
+ if (builder.isFeasible(true)) {
+ if (const ProgramState *state = PrevState->assume(V, true))
+ builder.generateNode(MarkBranch(state, Term, true), true);
+ else
+ builder.markInfeasible(true);
+ }
- // Process the false branch.
- if (builder.isFeasible(false)) {
- if (const ProgramState *state = PrevState->assume(V, false))
- builder.generateNode(MarkBranch(state, Term, false), false);
- else
- builder.markInfeasible(false);
- }
+ // Process the false branch.
+ if (builder.isFeasible(false)) {
+ if (const ProgramState *state = PrevState->assume(V, false))
+ builder.generateNode(MarkBranch(state, Term, false), false);
+ else
+ builder.markInfeasible(false);
+ }
- // Enqueue the results into the work list.
- Engine.enqueue(builder);
+ // Enqueue the results into the work list.
+ Engine.enqueue(builder);
+ }
}
/// processIndirectGoto - Called by CoreEngine. Used to generate successor