r177800 - [analyzer] Use SymExprs to represent '<loc> - <loc>' and '<loc> == <loc>'.

Jordan Rose jordan_rose at apple.com
Fri Mar 22 18:21:05 PDT 2013


Author: jrose
Date: Fri Mar 22 20:21:05 2013
New Revision: 177800

URL: http://llvm.org/viewvc/llvm-project?rev=177800&view=rev
Log:
[analyzer] Use SymExprs to represent '<loc> - <loc>' and '<loc> == <loc>'.

We just treat this as opaque symbols, but even that allows us to handle
simple cases where the same condition is tested twice. This is very common
in the STL, which means that any project using the STL gets spurious errors.

Part of <rdar://problem/13239003>.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
    cfe/trunk/test/Analysis/ptr-arith.c

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp?rev=177800&r1=177799&r2=177800&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Fri Mar 22 20:21:05 2013
@@ -508,22 +508,21 @@ SVal SimpleSValBuilder::evalBinOpNN(Prog
           // Otherwise, make a SymIntExpr out of the expression.
           return MakeSymIntVal(symIntExpr, op, *RHSValue, resultTy);
         }
+      }
 
-
-      } else if (isa<SymbolData>(Sym)) {
-        // Does the symbol simplify to a constant?  If so, "fold" the constant
-        // by setting 'lhs' to a ConcreteInt and try again.
-        if (const llvm::APSInt *Constant = state->getConstraintManager()
-                                                  .getSymVal(state, Sym)) {
-          lhs = nonloc::ConcreteInt(*Constant);
-          continue;
-        }
-
-        // Is the RHS a constant?
-        if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs))
-          return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
+      // Does the symbolic expression simplify to a constant?
+      // If so, "fold" the constant by setting 'lhs' to a ConcreteInt
+      // and try again.
+      ConstraintManager &CMgr = state->getConstraintManager();
+      if (const llvm::APSInt *Constant = CMgr.getSymVal(state, Sym)) {
+        lhs = nonloc::ConcreteInt(*Constant);
+        continue;
       }
 
+      // Is the RHS a constant?
+      if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs))
+        return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
+
       // Give up -- this is not a symbolic expression we can handle.
       return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
     }
@@ -682,11 +681,11 @@ SVal SimpleSValBuilder::evalBinOpLL(Prog
       // regions, though.
       return UnknownVal();
 
-    const MemSpaceRegion *LeftMS = LeftMR->getMemorySpace();
-    const MemSpaceRegion *RightMS = RightMR->getMemorySpace();
-    const MemSpaceRegion *UnknownMS = MemMgr.getUnknownRegion();
     const MemRegion *LeftBase = LeftMR->getBaseRegion();
     const MemRegion *RightBase = RightMR->getBaseRegion();
+    const MemSpaceRegion *LeftMS = LeftBase->getMemorySpace();
+    const MemSpaceRegion *RightMS = RightBase->getMemorySpace();
+    const MemSpaceRegion *UnknownMS = MemMgr.getUnknownRegion();
 
     // If the two regions are from different known memory spaces they cannot be
     // equal. Also, assume that no symbolic region (whose memory space is
@@ -789,7 +788,6 @@ SVal SimpleSValBuilder::evalBinOpLL(Prog
       }
 
       // If we get here, we have no way of comparing the ElementRegions.
-      return UnknownVal();
     }
 
     // See if both regions are fields of the same structure.
@@ -842,6 +840,13 @@ SVal SimpleSValBuilder::evalBinOpLL(Prog
       llvm_unreachable("Fields not found in parent record's definition");
     }
 
+    // At this point we're not going to get a good answer, but we can try
+    // conjuring an expression instead.
+    SymbolRef LHSSym = lhs.getAsLocSymbol();
+    SymbolRef RHSSym = rhs.getAsLocSymbol();
+    if (LHSSym && RHSSym)
+      return makeNonLoc(LHSSym, op, RHSSym, resultTy);
+
     // If we get here, we have no way of comparing the regions.
     return UnknownVal();
   }

Modified: cfe/trunk/test/Analysis/ptr-arith.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ptr-arith.c?rev=177800&r1=177799&r2=177800&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/ptr-arith.c (original)
+++ cfe/trunk/test/Analysis/ptr-arith.c Fri Mar 22 20:21:05 2013
@@ -167,3 +167,15 @@ void PR7527 (int *p) {
   if (((int) p) & 1) // not crash
     return;
 }
+
+void use_symbols(int *lhs, int *rhs) {
+  clang_analyzer_eval(lhs < rhs); // expected-warning{{UNKNOWN}}
+  if (lhs < rhs)
+    return;
+  clang_analyzer_eval(lhs < rhs); // expected-warning{{FALSE}}
+
+  clang_analyzer_eval(lhs - rhs); // expected-warning{{UNKNOWN}}
+  if ((lhs - rhs) != 5)
+    return;
+  clang_analyzer_eval((lhs - rhs) == 5); // expected-warning{{TRUE}}
+}





More information about the cfe-commits mailing list