r178685 - [analyzer] make peelOffOuterExpr in BugReporterVisitors recursively peel off select Exprs

Anna Zaks ganna at apple.com
Wed Apr 3 12:28:16 PDT 2013


Author: zaks
Date: Wed Apr  3 14:28:15 2013
New Revision: 178685

URL: http://llvm.org/viewvc/llvm-project?rev=178685&view=rev
Log:
[analyzer] make peelOffOuterExpr in BugReporterVisitors recursively peel off select Exprs

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
    cfe/trunk/test/Analysis/inlining/false-positive-suppression.c

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=178685&r1=178684&r2=178685&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Wed Apr  3 14:28:15 2013
@@ -789,36 +789,33 @@ static const MemRegion *getLocationRegio
   return 0;
 }
 
-static const Expr *peelOffOuterExpr(const Stmt *S,
+static const Expr *peelOffOuterExpr(const Expr *Ex,
                                     const ExplodedNode *N) {
-  if (const Expr *Ex = dyn_cast<Expr>(S)) {
-    Ex = Ex->IgnoreParenCasts();
-    if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Ex))
-      return EWC->getSubExpr();
-    if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Ex))
-      return OVE->getSourceExpr();
-
-    // Peel off the ternary operator.
-    if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
-      const Expr *CondEx = CO->getCond();
-
-      // Find a node where the value of the condition is known.
-      do {
-        ProgramStateRef State = N->getState();
-        SVal CondVal = State->getSVal(CondEx, N->getLocationContext());
-        ConditionTruthVal CondEvaluated = State->isNull(CondVal);
-        if (CondEvaluated.isConstrained()) {
-          if (CondEvaluated.isConstrainedTrue())
-            return CO->getFalseExpr();
-          else
-            return CO->getTrueExpr();
-        }
-        N = N->getFirstPred();
-      } while (N);
-      
-    }
+  Ex = Ex->IgnoreParenCasts();
+  if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Ex))
+    return peelOffOuterExpr(EWC->getSubExpr(), N);
+  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Ex))
+    return peelOffOuterExpr(OVE->getSourceExpr(), N);
+
+  // Peel off the ternary operator.
+  if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
+    const Expr *CondEx = CO->getCond();
+
+    // Find a node where the value of the condition is known.
+    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);
+      }
+      N = N->getFirstPred();
+    } while (N);
   }
-  return 0;
+  return Ex;
 }
 
 bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
@@ -828,8 +825,12 @@ bool bugreporter::trackNullOrUndefValue(
   if (!S || !N)
     return false;
 
-  if (const Expr *Ex = peelOffOuterExpr(S, N))
-    S = Ex;
+  if (const Expr *Ex = dyn_cast<Expr>(S)) {
+    Ex = Ex->IgnoreParenCasts();
+    const Expr *PeeledEx = peelOffOuterExpr(Ex, N);
+    if (Ex != PeeledEx)
+      S = PeeledEx;
+  }
 
   const Expr *Inner = 0;
   if (const Expr *Ex = dyn_cast<Expr>(S)) {

Modified: cfe/trunk/test/Analysis/inlining/false-positive-suppression.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/false-positive-suppression.c?rev=178685&r1=178684&r2=178685&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/false-positive-suppression.c (original)
+++ cfe/trunk/test/Analysis/inlining/false-positive-suppression.c Wed Apr  3 14:28:15 2013
@@ -240,4 +240,29 @@ int ternaryRetNull(char cond) {
 #endif
 }
 
+// Test suppression of nested conditional operators.
+int testConditionalOperatorSuppress(int x) {
+  return *(x ? getNull() : getPtr());
+#ifndef SUPPRESSED
+  // expected-warning at -2 {{Dereference of null pointer}}
+#endif
+}
+int testNestedConditionalOperatorSuppress(int x) {
+  return *(x ? (x ? getNull() : getPtr()) : getPtr());
+#ifndef SUPPRESSED
+  // expected-warning at -2 {{Dereference of null pointer}}
+#endif
+}
+int testConditionalOperator(int x) {
+  return *(x ? 0 : getPtr()); // expected-warning {{Dereference of null pointer}}
+}
+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}}
+}
 





More information about the cfe-commits mailing list