From: Ted Kremenek Date: Wed, 25 Feb 2009 23:32:10 +0000 (+0000) Subject: Fix subtle bug in EvalEagerlyAssume: Check if the previous node was at the same state... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b293902c5cfa18365ffb0e00763849c9808a2ad1;p=clang Fix subtle bug in EvalEagerlyAssume: Check if the previous node was at the same statement. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65486 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 797b0ae0cd..4febc3ba91 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -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()) diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 08c8d9bf01..25cd4f7eed 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -266,7 +266,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { if (EagerlyAssume && (B->isRelationalOp() || B->isEqualityOp())) { NodeSet Tmp; VisitBinaryOperator(cast(S), Pred, Tmp); - EvalEagerlyAssume(Dst, Tmp); + EvalEagerlyAssume(Dst, Tmp, cast(S)); } else VisitBinaryOperator(cast(S), Pred, Dst); @@ -1359,20 +1359,28 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred, static std::pair 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(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(P) || cast(P).getStmt() != Ex) { + Dst.Add(Pred); + continue; + } + const GRState* state = Pred->getState(); - SVal V = GetSVal(state, S); + SVal V = GetSVal(state, Ex); if (isa(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(S), - MakeConstantVal(1U, cast(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(S), - MakeConstantVal(0U, cast(S))); - Dst.Add(Builder->generateNode(PostStmtCustom(S, &EagerlyAssumeTag), + stateFalse = BindExpr(stateFalse, Ex, MakeConstantVal(0U, Ex)); + Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag), stateFalse, Pred)); } }