aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2011-10-18 23:06:21 +0000
committerAnna Zaks <ganna@apple.com>2011-10-18 23:06:21 +0000
commitcd656cab3fa3dd4b0c974c6ae1c0e60880b18c22 (patch)
tree95fabbc9cca21c9cd2a8a347d00536d9d9db0c7a /lib/StaticAnalyzer
parentad62deeb70e97da6bd514dd390ea1ce6af6ad81d (diff)
[analyzer] Modularize builder use in processBranch.
Take advantage of the new builders for branch processing. As part of this change pass generic NodeBuilder (instead of BranchNodeBuilder) to the BranchCondition callback and remove the unused methods form BranchBuilder. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142448 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer')
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp18
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp15
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp89
4 files changed, 60 insertions, 64 deletions
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 8663893f2e..451fa91b3a 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -49,20 +49,27 @@ class UndefBranchChecker : public Checker<check::BranchCondition> {
};
public:
- void checkBranchCondition(const Stmt *Condition, BranchNodeBuilder &Builder,
+ void checkBranchCondition(const Stmt *Condition, NodeBuilder &Builder,
ExprEngine &Eng) const;
};
}
void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
- BranchNodeBuilder &Builder,
+ NodeBuilder &Builder,
ExprEngine &Eng) const {
const ProgramState *state = Builder.getState();
SVal X = state->getSVal(Condition);
if (X.isUndef()) {
- // Generate a sink node.
- ExplodedNode *N = Builder.generateNode(Condition, state, 0, true);
+ // TODO: The PP will be generated with the correct tag by the CheckerManager
+ // after we migrate the callback to CheckerContext.
+ const ProgramPointTag *Tag = 0;
+ ProgramPoint PP = PostCondition(Condition,
+ Builder.getPredecessor()->getLocationContext(), Tag);
+ // Generate a sink node, which implicitly marks both outgoing branches as
+ // infeasible.
+ ExplodedNode *N = Builder.generateNode(PP, state,
+ Builder.getPredecessor(), true);
if (N) {
if (!BT)
BT.reset(
@@ -102,9 +109,6 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
Eng.getBugReporter().EmitReport(R);
}
-
- Builder.markInfeasible(true);
- Builder.markInfeasible(false);
}
}
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index acacfb0e18..d47033a70e 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -297,7 +297,7 @@ void CheckerManager::runCheckersForEndPath(EndOfFunctionNodeBuilder &B,
/// \brief Run checkers for branch condition.
void CheckerManager::runCheckersForBranchCondition(const Stmt *condition,
- BranchNodeBuilder &B,
+ NodeBuilder &B,
ExprEngine &Eng) {
for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) {
CheckBranchConditionFunc fn = BranchConditionCheckers[i];
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index d1c1e39d59..91aa9a567c 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -602,21 +602,6 @@ StmtNodeBuilder::generateNodeInternal(const ProgramPoint &Loc,
return NULL;
}
-// This function generate a new ExplodedNode but not a new branch(block edge).
-// Creates a transition from the Builder's top predecessor.
-ExplodedNode *BranchNodeBuilder::generateNode(const Stmt *Condition,
- const ProgramState *State,
- const ProgramPointTag *Tag,
- bool MarkAsSink) {
- ProgramPoint PP = PostCondition(Condition,
- BuilderPred->getLocationContext(), Tag);
- ExplodedNode *N = generateNodeImpl(PP, State, BuilderPred, MarkAsSink);
- assert(N);
- // TODO: This needs to go - we should not change Pred!!!
- BuilderPred = N;
- return N;
-}
-
ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
bool branch,
ExplodedNode *NodePred) {
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