aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp8
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp41
2 files changed, 31 insertions, 18 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index eaba5eedb5..f141392cbd 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -62,7 +62,8 @@ ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled)
*this),
SymMgr(StateMgr.getSymbolManager()),
svalBuilder(StateMgr.getSValBuilder()),
- EntryNode(NULL), currentStmt(NULL),
+ EntryNode(NULL),
+ currentStmt(NULL), currentStmtIdx(0), currentBuilderContext(0),
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
RaiseSel(GetNullarySelector("raise", getContext())),
ObjCGCEnabled(gcEnabled), BR(mgr, *this) {
@@ -229,6 +230,9 @@ void ExprEngine::ProcessStmt(const CFGStmt S, StmtNodeBuilder& builder,
StateMgr.recycleUnusedStates();
currentStmt = S.getStmt();
+ currentStmtIdx = builder.getIndex();
+ currentBuilderContext = &builder.getContext();
+
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
currentStmt->getLocStart(),
"Error evaluating statement");
@@ -432,7 +436,7 @@ void ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D,
}
void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
- ExplodedNodeSet &Dst) {
+ ExplodedNodeSet &Dst) {
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
S->getLocStart(),
"Error evaluating statement");
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 68ccc59ac9..eeb6b44ef2 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -530,9 +530,15 @@ VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
ExplodedNode *Pred,
- ExplodedNodeSet &Dst) {
+ ExplodedNodeSet &Dst) {
+ Builder->takeNodes(Pred);
+ PureStmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
+ bool IncDec = false;
switch (U->getOpcode()) {
default:
+ Builder->addNodes(Pred);
+ IncDec = true;
+ VisitIncrementDecrementOperator(U, Pred, Dst);
break;
case UO_Real: {
const Expr *Ex = U->getSubExpr()->IgnoreParens();
@@ -544,17 +550,16 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
// Just report "Unknown."
- Dst.Add(*I);
continue;
}
// For all other types, UO_Real is an identity operation.
assert (U->getType() == Ex->getType());
const ProgramState *state = (*I)->getState();
- MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex)));
+ Bldr.generateNode(U, *I, state->BindExpr(U, state->getSVal(Ex)));
}
- return;
+ break;
}
case UO_Imag: {
@@ -567,17 +572,16 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
// Just report "Unknown."
- Dst.Add(*I);
continue;
}
// For all other types, UO_Imag returns 0.
const ProgramState *state = (*I)->getState();
SVal X = svalBuilder.makeZeroVal(Ex->getType());
- MakeNode(Dst, U, *I, state->BindExpr(U, X));
+ Bldr.generateNode(U, *I, state->BindExpr(U, X));
}
- return;
+ break;
}
case UO_Plus:
@@ -598,10 +602,10 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const ProgramState *state = (*I)->getState();
- MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex)));
+ Bldr.generateNode(U, *I, state->BindExpr(U, state->getSVal(Ex)));
}
- return;
+ break;
}
case UO_LNot:
@@ -619,7 +623,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
SVal V = state->getSVal(Ex);
if (V.isUnknownOrUndef()) {
- MakeNode(Dst, U, *I, state->BindExpr(U, V));
+ Bldr.generateNode(U, *I, state->BindExpr(U, V));
continue;
}
@@ -660,14 +664,19 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
break;
}
-
- MakeNode(Dst, U, *I, state);
+ Bldr.generateNode(U, *I, state);
}
-
- return;
+ break;
}
}
-
+
+ if (!IncDec)
+ Builder->addNodes(Dst);
+}
+
+void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst) {
// Handle ++ and -- (both pre- and post-increment).
assert (U->isIncrementDecrementOp());
ExplodedNodeSet Tmp;
@@ -729,7 +738,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// It isn't feasible for the original value to be null.
// Propagate this constraint.
Constraint = svalBuilder.evalEQ(state, SymVal,
- svalBuilder.makeZeroVal(U->getType()));
+ svalBuilder.makeZeroVal(U->getType()));
state = state->assume(Constraint, false);