From f8ba2666e1ba6d8717740ae3673cddcf416e623f Mon Sep 17 00:00:00 2001 From: Gabor Horvath Date: Tue, 10 Oct 2017 11:01:49 +0000 Subject: [PATCH] [analyzer] Implement pointer arithmetic on constants Patch by: Rafael Stahl! Differential Revision: https://reviews.llvm.org/D37478 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315296 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 6 ++++ test/Analysis/pointer-arithmetic.c | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/Analysis/pointer-arithmetic.c diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index bb4c2a6b52..a5b5744c3f 100644 --- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -922,6 +922,10 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state, if (rhs.isZeroConstant()) return lhs; + // Perserve the null pointer so that it can be found by the DerefChecker. + if (lhs.isZeroConstant()) + return lhs; + // We are dealing with pointer arithmetic. // Handle pointer arithmetic on constant values. @@ -937,6 +941,8 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state, // Offset the increment by the pointer size. llvm::APSInt Multiplicand(rightI.getBitWidth(), /* isUnsigned */ true); + QualType pointeeType = resultTy->getPointeeType(); + Multiplicand = getContext().getTypeSizeInChars(pointeeType).getQuantity(); rightI *= Multiplicand; // Compute the adjusted pointer. diff --git a/test/Analysis/pointer-arithmetic.c b/test/Analysis/pointer-arithmetic.c new file mode 100644 index 0000000000..575dfffc01 --- /dev/null +++ b/test/Analysis/pointer-arithmetic.c @@ -0,0 +1,30 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s + +int test1() { + int *p = (int *)sizeof(int); + p -= 1; + return *p; // expected-warning {{Dereference of null pointer}} +} + +int test2() { + int *p = (int *)sizeof(int); + p -= 2; + p += 1; + return *p; // expected-warning {{Dereference of null pointer}} +} + +int test3() { + int *p = (int *)sizeof(int); + p++; + p--; + p--; + return *p; // expected-warning {{Dereference of null pointer}} +} + +int test4() { + // This is a special case where pointer arithmetic is not calculated to + // preserve useful warnings on dereferences of null pointers. + int *p = 0; + p += 1; + return *p; // expected-warning {{Dereference of null pointer}} +} -- 2.40.0