aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-12-09 12:16:07 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-12-09 12:16:07 +0000
commit78c98fad2cf17629b8659fe680ad92a548d1a5ea (patch)
tree52524145a9776d2ed0df353e2dd047e1d1dc1c62
parentb94ffa4a641b71c7c6155cddc7dc384f8a45c9f1 (diff)
Use a temporary destination set such that we can clear fake auto transitions.
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
-rw-r--r--lib/Analysis/GRExprEngine.cpp27
1 files changed, 24 insertions, 3 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index daa249f901..a31b57331b 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -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;
}