]> granicus.if.org Git - clang/commitdiff
Update ExprEngine's handling of ternary operators to find the ternary expression
authorTed Kremenek <kremenek@apple.com>
Wed, 25 Jul 2012 21:58:25 +0000 (21:58 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 25 Jul 2012 21:58:25 +0000 (21:58 +0000)
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

lib/StaticAnalyzer/Core/ExprEngineC.cpp
test/Analysis/misc-ps.c

index 0254b756ee4c531d439b4d48ebf7b336d69501b1..4bcc0fbd100ca8d622d45daca3374decd910b04a 100644 (file)
@@ -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::
index f81b0ddc68d200a209c6814019a574a05d3f1e4e..8ff710b12f56f38239778f815d84b4ac5a8c26d9 100644 (file)
@@ -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);
+}
+