From d3254b446211d3f1a455c4f2247dc910df68d69f Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Wed, 3 Apr 2013 21:34:12 +0000 Subject: [analyzer] Allow tracknullOrUndef look through the ternary operator even when condition is unknown Improvement of r178684 and r178685. Jordan has pointed out that I should not rely on the value of the condition to know which expression branch has been taken. It will not work in cases the branch condition is an unknown value (ex: we do not track the constraints for floats). The better way of doing this would be to find out if the current node is the right or left successor of the node that has the ternary operator as a terminator (which is how this is done in other places, like ConditionBRVisitor). llvm-svn: 178701 --- .../StaticAnalyzer/Core/BugReporterVisitors.cpp | 30 ++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'clang/lib/StaticAnalyzer') diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 60a7e65254d..c3bbc3baf69 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -799,21 +799,25 @@ static const Expr *peelOffOuterExpr(const Expr *Ex, // Peel off the ternary operator. if (const ConditionalOperator *CO = dyn_cast(Ex)) { - const Expr *CondEx = CO->getCond(); - - // Find a node where the value of the condition is known. + // Find a node where the branching occured and find out which branch + // we took (true/false) by looking at the ExplodedGraph. + const ExplodedNode *NI = N; do { - ProgramStateRef State = N->getState(); - SVal CondVal = State->getSVal(CondEx, N->getLocationContext()); - ConditionTruthVal CondEvaluated = State->isNull(CondVal); - if (CondEvaluated.isConstrained()) { - if (CondEvaluated.isConstrainedTrue()) - return peelOffOuterExpr(CO->getFalseExpr(), N); - else - return peelOffOuterExpr(CO->getTrueExpr(), N); + ProgramPoint ProgPoint = NI->getLocation(); + if (Optional BE = ProgPoint.getAs()) { + const CFGBlock *srcBlk = BE->getSrc(); + if (const Stmt *term = srcBlk->getTerminator()) { + if (term == CO) { + bool TookTrueBranch = (*(srcBlk->succ_begin()) == BE->getDst()); + if (TookTrueBranch) + return peelOffOuterExpr(CO->getTrueExpr(), N); + else + return peelOffOuterExpr(CO->getFalseExpr(), N); + } + } } - N = N->getFirstPred(); - } while (N); + NI = NI->getFirstPred(); + } while (NI); } return Ex; } -- cgit v1.2.3