[analyzer] Fix crash on modeling of pointer arithmetic
authorAlexander Shaposhnikov <shal1t712@gmail.com>
Mon, 25 Sep 2017 19:32:33 +0000 (19:32 +0000)
committerAlexander Shaposhnikov <shal1t712@gmail.com>
Mon, 25 Sep 2017 19:32:33 +0000 (19:32 +0000)
This patch fixes analyzer's crash on the newly added test case
(see also https://bugs.llvm.org/show_bug.cgi?id=34374).
Pointers subtraction appears to be modeled incorrectly
in the following example:
  char* p;
  auto n = p - reinterpret_cast<char*>((unsigned long)1);
In this case the analyzer (built without this patch)
tries to create a symbolic value for the difference
treating reinterpret_cast<char*>((unsigned long)1)
as an integer, that is not correct.

Differential revision: https://reviews.llvm.org/D38214

Test plan: make check-all

llvm-svn: 314141

clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
clang/test/Analysis/ptr-arith.cpp

index f2aa201..bb4c2a6 100644 (file)
@@ -726,9 +726,11 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
     if (Optional<loc::ConcreteInt> rInt = rhs.getAs<loc::ConcreteInt>()) {
       // If one of the operands is a symbol and the other is a constant,
       // build an expression for use by the constraint manager.
-      if (SymbolRef lSym = lhs.getAsLocSymbol(true))
-        return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
-
+      if (SymbolRef lSym = lhs.getAsLocSymbol(true)) {
+        if (BinaryOperator::isComparisonOp(op))
+          return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+        return UnknownVal();
+      }
       // Special case comparisons to NULL.
       // This must come after the test if the LHS is a symbol, which is used to
       // build constraints. The address of any non-symbolic region is guaranteed
index 01adf47..1eec83c 100644 (file)
@@ -111,3 +111,9 @@ bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) {
   __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
   return y == x;
 }
+
+// Bug 34374
+bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
+  auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1);
+  return n == m;
+}