]> granicus.if.org Git - clang/commitdiff
Fix subtle bug in EvalEagerlyAssume: Check if the previous node was at the same state...
authorTed Kremenek <kremenek@apple.com>
Wed, 25 Feb 2009 23:32:10 +0000 (23:32 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 25 Feb 2009 23:32:10 +0000 (23:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65486 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/GRExprEngine.h
lib/Analysis/GRExprEngine.cpp

index 797b0ae0cd80c40f952de251268a1bfeac873506..4febc3ba9133473e9da2cb109dc0e2ef2845cf6b 100644 (file)
@@ -618,7 +618,7 @@ protected:
   /// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
   ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
   ///  with those assumptions.
-  void EvalEagerlyAssume(NodeSet& Dst, NodeSet& Src);
+  void EvalEagerlyAssume(NodeSet& Dst, NodeSet& Src, Expr *Ex);
   
   SVal EvalCast(SVal X, QualType CastT) {
     if (X.isUnknownOrUndef())
index 08c8d9bf01d0e6397c5239a6fa0e5dc8a0e60afd..25cd4f7eed4b9392c1429c32a1c7f73fb6d11b49 100644 (file)
@@ -266,7 +266,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
       if (EagerlyAssume && (B->isRelationalOp() || B->isEqualityOp())) {
         NodeSet Tmp;
         VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
-        EvalEagerlyAssume(Dst, Tmp);        
+        EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));        
       }
       else
         VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
@@ -1359,20 +1359,28 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,
 
 static std::pair<const void*,const void*> EagerlyAssumeTag(&EagerlyAssumeTag,0);
 
-void GRExprEngine::EvalEagerlyAssume(NodeSet &Dst, NodeSet &Src) {
+void GRExprEngine::EvalEagerlyAssume(NodeSet &Dst, NodeSet &Src, Expr *Ex) {
   for (NodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
     NodeTy *Pred = *I;
-    Stmt *S = cast<PostStmt>(Pred->getLocation()).getStmt();
+    
+    // Test if the previous node was as the same expression.  This can happen
+    // when the expression fails to evaluate to anything meaningful and
+    // (as an optimization) we don't generate a node.
+    ProgramPoint P = Pred->getLocation();    
+    if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
+      Dst.Add(Pred);      
+      continue;
+    }    
+
     const GRState* state = Pred->getState();    
-    SVal V = GetSVal(state, S);    
+    SVal V = GetSVal(state, Ex);    
     if (isa<nonloc::SymIntConstraintVal>(V)) {
       // First assume that the condition is true.
       bool isFeasible = false;
       const GRState *stateTrue = Assume(state, V, true, isFeasible);
       if (isFeasible) {
-        stateTrue = BindExpr(stateTrue, cast<Expr>(S),
-                             MakeConstantVal(1U, cast<Expr>(S)));        
-        Dst.Add(Builder->generateNode(PostStmtCustom(S, &EagerlyAssumeTag),
+        stateTrue = BindExpr(stateTrue, Ex, MakeConstantVal(1U, Ex));        
+        Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag),
                                       stateTrue, Pred));
       }
         
@@ -1380,9 +1388,8 @@ void GRExprEngine::EvalEagerlyAssume(NodeSet &Dst, NodeSet &Src) {
       isFeasible = false;
       const GRState *stateFalse = Assume(state, V, false, isFeasible);
       if (isFeasible) {
-        stateFalse = BindExpr(stateFalse, cast<Expr>(S),
-                              MakeConstantVal(0U, cast<Expr>(S)));
-        Dst.Add(Builder->generateNode(PostStmtCustom(S, &EagerlyAssumeTag),
+        stateFalse = BindExpr(stateFalse, Ex, MakeConstantVal(0U, Ex));
+        Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag),
                                       stateFalse, Pred));
       }
     }