a.sidorin created this revision. a.sidorin added reviewers: zaks.anna, dcoughlin, xazax.hun. a.sidorin added a subscriber: cfe-commits. a.sidorin set the repository for this revision to rL LLVM.
Currently, a default index type in CSA is 'int'. However, this assumption seems to be incorrect for 64-bit platforms where index may be 64-bit as well as the array size. For example, it leads to unexpected overflows while performing pointer arithmetics. Moreover, PointerDiffType and 'int' cannot be used as a common array index type because arrays may have size (and indexes) more than PTRDIFF_MAX but less than SIZE_MAX. Since maximum array size for 64 bits is SIZE_MAX/8, I propose to use 'long long' as a common index type, although it looks a bit hacky for 32 bit. Repository: rL LLVM http://reviews.llvm.org/D16063 Files: include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h test/Analysis/index-type.c Index: test/Analysis/index-type.c =================================================================== --- /dev/null +++ test/Analysis/index-type.c @@ -0,0 +1,38 @@ +// 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_ARRAY_SIZE 0x9000000000000000 +void testIndexTooBig64() { + char arr[ULONG_MAX/8-1]; + char *ptr = arr + ULONG_MAX; + ptr += 2; // don't overflow 64-bit index + *ptr = 42; // no-warning +} + +#endif Index: include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -65,7 +65,7 @@ SymMgr(context, BasicVals, alloc), MemMgr(context, alloc), StateMgr(stateMgr), - ArrayIndexTy(context.IntTy), + ArrayIndexTy(context.LongLongTy), ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {} virtual ~SValBuilder() {}
Index: test/Analysis/index-type.c =================================================================== --- /dev/null +++ test/Analysis/index-type.c @@ -0,0 +1,38 @@ +// 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_ARRAY_SIZE 0x9000000000000000 +void testIndexTooBig64() { + char arr[ULONG_MAX/8-1]; + char *ptr = arr + ULONG_MAX; + ptr += 2; // don't overflow 64-bit index + *ptr = 42; // no-warning +} + +#endif Index: include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -65,7 +65,7 @@ SymMgr(context, BasicVals, alloc), MemMgr(context, alloc), StateMgr(stateMgr), - ArrayIndexTy(context.IntTy), + ArrayIndexTy(context.LongLongTy), ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {} virtual ~SValBuilder() {}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits