r335803 - [analyzer] Use sufficiently large types for index bounds calculation.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 27 17:42:11 PDT 2018


Author: dergachev
Date: Wed Jun 27 17:42:11 2018
New Revision: 335803

URL: http://llvm.org/viewvc/llvm-project?rev=335803&view=rev
Log:
[analyzer] Use sufficiently large types for index bounds calculation.

The ProgramState::assumeInBound() API is used by checkers to make an assumption
that a certain array index is within the array's bounds (i.e. is greater than or
equal to 0 and is less than the length of the array). When the type of the
index was unspecified by the caller, it assumed that the type is 'int', which
caused some indices and sizes to truncate during calculations.

Use ArrayIndexTy by default instead, which is used by the analyzer to represent
index types and is currently hardcoded to long long.

Patch by Bevin Hansson!

Differential Revision: https://reviews.llvm.org/D46944

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
    cfe/trunk/test/Analysis/index-type.c

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=335803&r1=335802&r2=335803&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Wed Jun 27 17:42:11 2018
@@ -336,9 +336,8 @@ ProgramStateRef ProgramState::assumeInBo
 
   // Get the offset: the minimum value of the array index type.
   BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
-  // FIXME: This should be using ValueManager::ArrayindexTy...somehow.
   if (indexTy.isNull())
-    indexTy = Ctx.IntTy;
+    indexTy = svalBuilder.getArrayIndexType();
   nonloc::ConcreteInt Min(BVF.getMinValue(indexTy));
 
   // Adjust the index.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=335803&r1=335802&r2=335803&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Wed Jun 27 17:42:11 2018
@@ -1341,7 +1341,8 @@ RegionStoreManager::getSizeInElements(Pr
   // If a variable is reinterpreted as a type that doesn't fit into a larger
   // type evenly, round it down.
   // This is a signed value, since it's used in arithmetic with signed indices.
-  return svalBuilder.makeIntVal(RegionSize / EleSize, false);
+  return svalBuilder.makeIntVal(RegionSize / EleSize,
+                                svalBuilder.getArrayIndexType());
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/Analysis/index-type.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/index-type.c?rev=335803&r1=335802&r2=335803&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/index-type.c (original)
+++ cfe/trunk/test/Analysis/index-type.c Wed Jun 27 17:42:11 2018
@@ -1,5 +1,5 @@
-// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -DM32 -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -Wno-implicit-function-declaration -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -Wno-implicit-function-declaration -DM32 -verify %s
 // expected-no-diagnostics
 
 #define UINT_MAX (~0u)
@@ -36,4 +36,23 @@ void testIndexTooBig64() {
   *ptr = 42; // no-warning
 }
 
+#define SIZE 4294967296
+
+static unsigned size;
+static void * addr;
+static unsigned buf[SIZE];
+
+void testOutOfBounds() {
+  // Not out of bounds.
+  buf[SIZE-1] = 1; // no-warning
+}
+
+void testOutOfBoundsCopy1() {
+  memcpy(buf, addr, size); // no-warning
+}
+
+void testOutOfBoundsCopy2() {
+  memcpy(addr, buf, size); // no-warning
+}
+
 #endif




More information about the cfe-commits mailing list