diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-07-25 21:58:25 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-07-25 21:58:25 +0000 |
commit | 469841a8e0967f038aa0f78e1926ce82e06248c7 (patch) | |
tree | 30f4a062041338d399dd6b82fbe443f2ab2be7e2 | |
parent | 2ca5af239af48ed5c6af62ae03cd39c246af06db (diff) |
Update ExprEngine's handling of ternary operators to find the ternary expression
value by scanning the path, rather than assuming we have visited the '?:' operator
as a terminator (which sets a value indicating which expression to grab the
final ternary expression value from).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160760 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineC.cpp | 28 | ||||
-rw-r--r-- | test/Analysis/misc-ps.c | 7 |
2 files changed, 26 insertions, 9 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 0254b756ee..4bcc0fbd10 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -590,17 +590,27 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst) { StmtNodeBuilder B(Pred, Dst, *currentBuilderContext); - ProgramStateRef state = Pred->getState(); const LocationContext *LCtx = Pred->getLocationContext(); - SVal X = state->getSVal(Ex, LCtx); - assert (X.isUndef()); - const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData(); - assert(SE); - X = state->getSVal(SE, LCtx); - - // Make sure that we invalidate the previous binding. - B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, X, true)); + + // Assume that the last CFGElement visited is the value of + // the guarded expression. + ExplodedNode *N = Pred; + SVal V; + while (N) { + ProgramPoint P = N->getLocation(); + if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) { + const Expr *Ex = cast<Expr>(PS->getStmt()); + V = state->getSVal(Ex, LCtx); + break; + } + assert(N->pred_size() == 1); + N = *N->pred_begin(); + } + assert(N); + + // Generate a new node with the binding from the appropriate path. + B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true)); } void ExprEngine:: diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c index f81b0ddc68..8ff710b12f 100644 --- a/test/Analysis/misc-ps.c +++ b/test/Analysis/misc-ps.c @@ -126,3 +126,10 @@ void rdar10686586() { } } +// This example tests CFG handling of '||' nested in a ternary expression, +// and seeing that the analyzer doesn't crash. +int isctype(char c, unsigned long f) +{ + return (c < 1 || c > 10) ? 0 : !!(c & f); +} + |