diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 60a7e65254dc..c3bbc3baf69b 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; } diff --git a/clang/test/Analysis/inlining/false-positive-suppression.c b/clang/test/Analysis/inlining/false-positive-suppression.c index 248d854dbc29..a836d9c62433 100644 --- a/clang/test/Analysis/inlining/false-positive-suppression.c +++ b/clang/test/Analysis/inlining/false-positive-suppression.c @@ -260,9 +260,10 @@ int testNestedConditionalOperator(int x) { return *(x ? (x ? 0 : getPtr()) : getPtr()); // expected-warning {{Dereference of null pointer}} } -// False Positve - we are unable to suppress this case because the condition is -// float. int testConditionalOperatorSuppressFloatCond(float x) { - return *(x ? getNull() : getPtr()); // expected-warning {{Dereference of null pointer}} + return *(x ? getNull() : getPtr()); +#ifndef SUPPRESSED + // expected-warning@-2 {{Dereference of null pointer}} +#endif }