llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-static-analyzer-1 Author: Balázs Kéri (balazske) <details> <summary>Changes</summary> Checker was tested on 16 projects. The only results were the offset calculations that were considered as valid (faulty) cases already. https://codechecker-demo.eastus.cloudapp.azure.com/Default/reports?run=vim_v8.2.1920_pointersub_c&is-unique=off&diff-type=New&checker-name=alpha.core.PointerSub https://codechecker-demo.eastus.cloudapp.azure.com/Default/reports?run=protobuf_v3.13.0_pointersub_cpp&is-unique=off&diff-type=New&checker-name=alpha.core.PointerSub --- Full diff: https://github.com/llvm/llvm-project/pull/107596.diff 6 Files Affected: - (modified) clang/docs/analyzer/checkers.rst (+43-43) - (modified) clang/include/clang/StaticAnalyzer/Checkers/Checkers.td (+5-5) - (modified) clang/test/Analysis/analyzer-enabled-checkers.c (+1) - (modified) clang/test/Analysis/pointer-sub-notes.c (+1-1) - (modified) clang/test/Analysis/pointer-sub.c (+1-1) - (modified) clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c (+1) ``````````diff diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 847bf4baf74887..05e7b985d52cec 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -170,6 +170,49 @@ disable this behavior with the option obj->x = 1; // warn } +.. _core-PointerSub: + +core.PointerSub (C) +""""""""""""""""""" +Check for pointer subtractions on two pointers pointing to different memory +chunks. According to the C standard §6.5.6 only subtraction of pointers that +point into (or one past the end) the same array object is valid (for this +purpose non-array variables are like arrays of size 1). This checker only +searches for different memory objects at subtraction, but does not check if the +array index is correct. Furthermore, only cases are reported where +stack-allocated objects are involved (no warnings on pointers to memory +allocated by `malloc`). + +.. code-block:: c + + void test() { + int a, b, c[10], d[10]; + int x = &c[3] - &c[1]; + x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays + x = (&a + 1) - &a; + x = &b - &a; // warn: 'a' and 'b' are different variables + } + + struct S { + int x[10]; + int y[10]; + }; + + void test1() { + struct S a[10]; + struct S b; + int d = &a[4] - &a[6]; + d = &a[0].x[3] - &a[0].x[1]; + d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects + d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object + d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it + } + +There may be existing applications that use code like above for calculating +offsets of members in a structure, using pointer subtractions. This is still +undefined behavior according to the standard and code like this can be replaced +with the `offsetof` macro. + .. _core-StackAddressEscape: core.StackAddressEscape (C) @@ -2526,49 +2569,6 @@ Check for pointer arithmetic on locations other than array elements. p = &x + 1; // warn } -.. _alpha-core-PointerSub: - -alpha.core.PointerSub (C) -""""""""""""""""""""""""" -Check for pointer subtractions on two pointers pointing to different memory -chunks. According to the C standard §6.5.6 only subtraction of pointers that -point into (or one past the end) the same array object is valid (for this -purpose non-array variables are like arrays of size 1). This checker only -searches for different memory objects at subtraction, but does not check if the -array index is correct. Furthermore, only cases are reported where -stack-allocated objects are involved (no warnings on pointers to memory -allocated by `malloc`). - -.. code-block:: c - - void test() { - int a, b, c[10], d[10]; - int x = &c[3] - &c[1]; - x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays - x = (&a + 1) - &a; - x = &b - &a; // warn: 'a' and 'b' are different variables - } - - struct S { - int x[10]; - int y[10]; - }; - - void test1() { - struct S a[10]; - struct S b; - int d = &a[4] - &a[6]; - d = &a[0].x[3] - &a[0].x[1]; - d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects - d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object - d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it - } - -There may be existing applications that use code like above for calculating -offsets of members in a structure, using pointer subtractions. This is still -undefined behavior according to the standard and code like this can be replaced -with the `offsetof` macro. - .. _alpha-core-StackAddressAsyncEscape: alpha.core.StackAddressAsyncEscape (C) diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 585246547b3dce..f4167b18b4879a 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -257,6 +257,11 @@ def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">, Documentation<NotDocumented>, Hidden; +def PointerSubChecker : Checker<"PointerSub">, + HelpText<"Check for pointer subtractions on two pointers pointing to " + "different memory chunks">, + Documentation<HasDocumentation>; + } // end "core" let ParentPackage = CoreAlpha in { @@ -291,11 +296,6 @@ def PointerArithChecker : Checker<"PointerArithm">, "elements">, Documentation<HasDocumentation>; -def PointerSubChecker : Checker<"PointerSub">, - HelpText<"Check for pointer subtractions on two pointers pointing to " - "different memory chunks">, - Documentation<HasDocumentation>; - def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">, HelpText<"Check for division by variable that is later compared against 0. " "Either the comparison is useless or there is division by zero.">, diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index e605c62a66ad0e..db0c2f8366e38c 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -19,6 +19,7 @@ // CHECK-NEXT: core.NonNullParamChecker // CHECK-NEXT: core.NonnilStringConstants // CHECK-NEXT: core.NullDereference +// CHECK-NEXT: core.PointerSub // CHECK-NEXT: core.StackAddrEscapeBase // CHECK-NEXT: core.StackAddressEscape // CHECK-NEXT: core.UndefinedBinaryOperatorResult diff --git a/clang/test/Analysis/pointer-sub-notes.c b/clang/test/Analysis/pointer-sub-notes.c index 59681b4e7555af..95653fb352dbd9 100644 --- a/clang/test/Analysis/pointer-sub-notes.c +++ b/clang/test/Analysis/pointer-sub-notes.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.PointerSub -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core.PointerSub -analyzer-output=text -verify %s void different_1() { int a[3]; // expected-note{{Array at the left-hand side of subtraction}} diff --git a/clang/test/Analysis/pointer-sub.c b/clang/test/Analysis/pointer-sub.c index cf9eac1abc2dcc..649a60f545e810 100644 --- a/clang/test/Analysis/pointer-sub.c +++ b/clang/test/Analysis/pointer-sub.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.PointerSub -analyzer-output=text-minimal -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text-minimal -verify %s void f1(void) { int x, y, z[10]; diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c index 345a4e8f44efd1..7cf20011ba81ca 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c +++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -27,6 +27,7 @@ // CHECK-NEXT: core.NonNullParamChecker // CHECK-NEXT: core.NonnilStringConstants // CHECK-NEXT: core.NullDereference +// CHECK-NEXT: core.PointerSub // CHECK-NEXT: core.StackAddrEscapeBase // CHECK-NEXT: core.StackAddressEscape // CHECK-NEXT: core.UndefinedBinaryOperatorResult `````````` </details> https://github.com/llvm/llvm-project/pull/107596 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits