浏览代码

[analyzer] Fix crash on modeling of pointer arithmetic

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


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314141 91177308-0d34-0410-b5e6-96231b3b80d8
Alexander Shaposhnikov 8 年之前
父节点
当前提交
31d5daeb5c
共有 2 个文件被更改,包括 11 次插入3 次删除
  1. 5 3
      lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  2. 6 0
      test/Analysis/ptr-arith.cpp

+ 5 - 3
lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp

@@ -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

+ 6 - 0
test/Analysis/ptr-arith.cpp

@@ -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;
+}