[analyzer] Use a wider integer type for an array index.

Avoids unexpected overflows while performing pointer arithmetics in 64-bit code.
Moreover, neither PointerDiffType nor 'int' can be used as a common array index
type because arrays may have size (and indexes) more than PTRDIFF_MAX but less
than SIZE_MAX.

Patch by Aleksei Sidorin!

Differential Revision: http://reviews.llvm.org/D16063

llvm-svn: 259345
This commit is contained in:
Artem Dergachev 2016-02-01 09:29:17 +00:00
parent c2c8ca1ce3
commit f8d0f18fac
2 changed files with 40 additions and 1 deletions

View File

@ -65,7 +65,7 @@ public:
SymMgr(context, BasicVals, alloc),
MemMgr(context, alloc),
StateMgr(stateMgr),
ArrayIndexTy(context.IntTy),
ArrayIndexTy(context.LongLongTy),
ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
virtual ~SValBuilder() {}

View File

@ -0,0 +1,39 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s
// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -DM32 -verify %s
// expected-no-diagnostics
#define UINT_MAX (~0u)
#ifdef M32
#define X86_ARRAY_SIZE (UINT_MAX/2 + 4)
void testIndexTooBig() {
char arr[X86_ARRAY_SIZE];
char *ptr = arr + UINT_MAX/2;
ptr += 2; // index shouldn't overflow
*ptr = 42; // no-warning
}
#else // 64-bit tests
#define ARRAY_SIZE 0x100000000
void testIndexOverflow64() {
char arr[ARRAY_SIZE];
char *ptr = arr + UINT_MAX/2;
ptr += 2; // don't overflow 64-bit index
*ptr = 42; // no-warning
}
#define ULONG_MAX (~0ul)
#define BIG_INDEX (ULONG_MAX/16)
void testIndexTooBig64() {
char arr[ULONG_MAX/8-1];
char *ptr = arr + BIG_INDEX;
ptr += 2; // don't overflow 64-bit index
*ptr = 42; // no-warning
}
#endif