r178684 - [analyzer] Properly handle the ternary operator in trackNullOrUndefValue

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


Author: zaks
Date: Wed Apr  3 14:28:12 2013
New Revision: 178684

URL: http://llvm.org/viewvc/llvm-project?rev=178684&view=rev
Log:
[analyzer] Properly handle the ternary operator in trackNullOrUndefValue

1) Look for the node where the condition expression is live when checking if
it is constrained to true or false.

2) Fix a bug in ProgramState::isNull, which was masking the problem. When
the expression is not a symbol (,which is the case when it is Unknown) return
unconstrained value, instead of value constrained to “false”!
(Thankfully other callers of isNull have not been effected by the bug.)

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.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=178684&r1=178683&r2=178684&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Wed Apr  3 14:28:12 2013
@@ -800,14 +800,22 @@ static const Expr *peelOffOuterExpr(cons
 
     // Peel off the ternary operator.
     if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
-      ProgramStateRef State = N->getState();
-      SVal CondVal = State->getSVal(CO->getCond(), N->getLocationContext());
-      if (State->isNull(CondVal).isConstrainedTrue()) {
-        return CO->getTrueExpr();
-      } else {
-        assert(State->isNull(CondVal).isConstrainedFalse());
-        return CO->getFalseExpr();
-      }
+      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);
+      
     }
   }
   return 0;
@@ -820,9 +828,8 @@ bool bugreporter::trackNullOrUndefValue(
   if (!S || !N)
     return false;
 
-  if (const Expr *Ex = peelOffOuterExpr(S, N)) {
+  if (const Expr *Ex = peelOffOuterExpr(S, N))
     S = Ex;
-  }
 
   const Expr *Inner = 0;
   if (const Expr *Ex = dyn_cast<Expr>(S)) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=178684&r1=178683&r2=178684&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Wed Apr  3 14:28:12 2013
@@ -380,9 +380,13 @@ ConditionTruthVal ProgramState::isNull(S
   if (V.isZeroConstant())
     return true;
 
+  if (V.isConstant())
+    return false;
+  
   SymbolRef Sym = V.getAsSymbol();
   if (!Sym)
-    return false;
+    return ConditionTruthVal();
+  
   return getStateManager().ConstraintMgr->isNull(this, Sym);
 }
 

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=178684&r1=178683&r2=178684&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:12 2013
@@ -9,6 +9,8 @@ int *getNull() {
   return 0;
 }
 
+int* getPtr();
+
 int *dynCastToInt(void *ptr) {
   if (opaquePropertyCheck(ptr))
     return (int *)ptr;
@@ -219,9 +221,10 @@ int derefAssignment(int *p) {
   // expected-warning at -2 {{Dereference of null pointer}}
 #endif
 }
+
 void ternaryAssignment(char cond) {
   static int x;
-  int *p = cond ? &x : getNull();
+  int *p = cond ? getNull() : getPtr();
   derefAssignment(p);
 }
 





More information about the cfe-commits mailing list