]> granicus.if.org Git - clang/commitdiff
Use a temporary destination set such that we can clear fake auto transitions.
authorZhongxing Xu <xuzhongxing@gmail.com>
Wed, 9 Dec 2009 12:16:07 +0000 (12:16 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Wed, 9 Dec 2009 12:16:07 +0000 (12:16 +0000)
Otherwise, even when real evaluation occurs, the previous fake auto
transitions would still be in the destination set, causing fake state
bifurcation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90967 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/GRExprEngine.cpp

index daa249f901cd947e1140fba2e22f1a9bc91e9271..a31b57331b21fae5bbce2a077c96697196479f25 100644 (file)
@@ -152,13 +152,26 @@ void GRExprEngine::CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
                                           ExplodedNodeSet &Dst,
                                           const GRState *state,
                                           ExplodedNode *Pred) {
+  bool Evaluated = false;
+  ExplodedNodeSet DstTmp;
+
   for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
     void *tag = I->first;
     Checker *checker = I->second;
 
-    if (checker->GR_EvalNilReceiver(Dst, *Builder, *this, ME, Pred, state, tag))
+    if (checker->GR_EvalNilReceiver(DstTmp, *Builder, *this, ME, Pred, state,
+                                    tag)) {
+      Evaluated = true;
       break;
+    } else
+      // The checker didn't evaluate the expr. Restore the Dst.
+      DstTmp.clear();
   }
+
+  if (Evaluated)
+    Dst.insert(DstTmp);
+  else
+    Dst.insert(Pred);
 }
 
 // CheckerEvalCall returns true if one of the checkers processed the node.
@@ -168,17 +181,25 @@ bool GRExprEngine::CheckerEvalCall(const CallExpr *CE,
                                    ExplodedNodeSet &Dst, 
                                    ExplodedNode *Pred) {
   bool Evaluated = false;
+  ExplodedNodeSet DstTmp;
 
   for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
     void *tag = I->first;
     Checker *checker = I->second;
 
-    if (checker->GR_EvalCallExpr(Dst, *Builder, *this, CE, Pred, tag)) {
+    if (checker->GR_EvalCallExpr(DstTmp, *Builder, *this, CE, Pred, tag)) {
       Evaluated = true;
       break;
-    }
+    } else
+      // The checker didn't evaluate the expr. Restore the DstTmp set.
+      DstTmp.clear();
   }
 
+  if (Evaluated)
+    Dst.insert(DstTmp);
+  else
+    Dst.insert(Pred);
+
   return Evaluated;
 }