]> granicus.if.org Git - clang/commitdiff
[analyzer] Use sufficiently large types for index bounds calculation.
authorArtem Dergachev <artem.dergachev@gmail.com>
Thu, 28 Jun 2018 00:42:11 +0000 (00:42 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Thu, 28 Jun 2018 00:42:11 +0000 (00:42 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335803 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/ProgramState.cpp
lib/StaticAnalyzer/Core/RegionStore.cpp
test/Analysis/index-type.c

index 141863d2ac8aa2e8c2d53b8266aaa925b27ffddd..2b401607293b7c383a22a51f4ea97abc6cd50a84 100644 (file)
@@ -336,9 +336,8 @@ ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
 
   // 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.
index acb6eeab8d915803e7ad47aee928bd6e5fe775cc..db6449e6d5f344cac6741943880c865327b45988 100644 (file)
@@ -1341,7 +1341,8 @@ RegionStoreManager::getSizeInElements(ProgramStateRef state,
   // 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());
 }
 
 //===----------------------------------------------------------------------===//
index b86913b996f6e959f390f78f4f60736cb06ba8f4..123dcd65bd7ca81360ed85bed6f522e5199f85a4 100644 (file)
@@ -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