From 02b64d46a0ab8da426dadb1873ead648c8ef70e6 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 23 Aug 2013 07:19:22 +0000 Subject: [analyzer] Refactor conditional expression evaluating code Summary: Instead of digging through the ExplodedGraph, to figure out which edge brought us here, I compute the value of conditional expression by looking at the sub-expression values. To do this, I needed to change the liveness algorithm a bit -- now, the full conditional expression also depends on all atomic sub-expressions, not only the outermost ones. Reviewers: jordan_rose CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1340 llvm-svn: 189090 --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 36 +++++++++++++++++++++------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngine.cpp') diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 552b2eca26e..6aa9174ad6e 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1343,12 +1343,24 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, return; } + SValBuilder &SVB = Pred->getState()->getStateManager().getSValBuilder(); + SVal TrueVal = SVB.makeTruthVal(true); + SVal FalseVal = SVB.makeTruthVal(false); // Resolve the condition in the precense of nested '||' and '&&'. if (const Expr *Ex = dyn_cast(Condition)) Condition = Ex->IgnoreParens(); - Condition = ResolveCondition(Condition, BldCtx.getBlock()); + + // Cast truth values to the correct type. + if (const Expr *Ex = dyn_cast(Condition)) { + TrueVal = SVB.evalCast(TrueVal, Ex->getType(), + getContext().getLogicalOperationType()); + FalseVal = SVB.evalCast(FalseVal, Ex->getType(), + getContext().getLogicalOperationType()); + } + + PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), Condition->getLocStart(), "Error evaluating branch"); @@ -1391,31 +1403,37 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, } } + ProgramStateRef StTrue, StFalse; + // If the condition is still unknown, give up. if (X.isUnknownOrUndef()) { - builder.generateNode(PrevState, true, PredI); - builder.generateNode(PrevState, false, PredI); + + StTrue = PrevState->BindExpr(Condition, BldCtx.LC, TrueVal); + StFalse = PrevState->BindExpr(Condition, BldCtx.LC, FalseVal); + + builder.generateNode(StTrue, true, PredI); + builder.generateNode(StFalse, false, PredI); continue; } DefinedSVal V = X.castAs(); - - ProgramStateRef StTrue, StFalse; tie(StTrue, StFalse) = PrevState->assume(V); // Process the true branch. if (builder.isFeasible(true)) { - if (StTrue) + if (StTrue) { + StTrue = StTrue->BindExpr(Condition, BldCtx.LC, TrueVal); builder.generateNode(StTrue, true, PredI); - else + } else builder.markInfeasible(true); } // Process the false branch. if (builder.isFeasible(false)) { - if (StFalse) + if (StFalse) { + StFalse = StFalse->BindExpr(Condition, BldCtx.LC, FalseVal); builder.generateNode(StFalse, false, PredI); - else + } else builder.markInfeasible(false); } } -- cgit v1.2.3