Skip to content

Commit 0d384fe

Browse files
authored
[clang][analyzer] Move 'alpha.core.PointerSub' checker into 'security.PointerSub' (#107596)
1 parent a87640c commit 0d384fe

File tree

5 files changed

+51
-55
lines changed

5 files changed

+51
-55
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,49 @@ Warn on ``mmap()`` calls with both writable and executable access.
15441544
// code
15451545
}
15461546
1547+
.. _security-PointerSub:
1548+
1549+
security.PointerSub (C)
1550+
"""""""""""""""""""""""
1551+
Check for pointer subtractions on two pointers pointing to different memory
1552+
chunks. According to the C standard §6.5.6 only subtraction of pointers that
1553+
point into (or one past the end) the same array object is valid (for this
1554+
purpose non-array variables are like arrays of size 1). This checker only
1555+
searches for different memory objects at subtraction, but does not check if the
1556+
array index is correct. Furthermore, only cases are reported where
1557+
stack-allocated objects are involved (no warnings on pointers to memory
1558+
allocated by `malloc`).
1559+
1560+
.. code-block:: c
1561+
1562+
void test() {
1563+
int a, b, c[10], d[10];
1564+
int x = &c[3] - &c[1];
1565+
x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays
1566+
x = (&a + 1) - &a;
1567+
x = &b - &a; // warn: 'a' and 'b' are different variables
1568+
}
1569+
1570+
struct S {
1571+
int x[10];
1572+
int y[10];
1573+
};
1574+
1575+
void test1() {
1576+
struct S a[10];
1577+
struct S b;
1578+
int d = &a[4] - &a[6];
1579+
d = &a[0].x[3] - &a[0].x[1];
1580+
d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects
1581+
d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object
1582+
d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it
1583+
}
1584+
1585+
There may be existing applications that use code like above for calculating
1586+
offsets of members in a structure, using pointer subtractions. This is still
1587+
undefined behavior according to the standard and code like this can be replaced
1588+
with the `offsetof` macro.
1589+
15471590
.. _security-putenv-stack-array:
15481591
15491592
security.PutenvStackArray (C)
@@ -2761,49 +2804,6 @@ Check for pointer arithmetic on locations other than array elements.
27612804
p = &x + 1; // warn
27622805
}
27632806
2764-
.. _alpha-core-PointerSub:
2765-
2766-
alpha.core.PointerSub (C)
2767-
"""""""""""""""""""""""""
2768-
Check for pointer subtractions on two pointers pointing to different memory
2769-
chunks. According to the C standard §6.5.6 only subtraction of pointers that
2770-
point into (or one past the end) the same array object is valid (for this
2771-
purpose non-array variables are like arrays of size 1). This checker only
2772-
searches for different memory objects at subtraction, but does not check if the
2773-
array index is correct. Furthermore, only cases are reported where
2774-
stack-allocated objects are involved (no warnings on pointers to memory
2775-
allocated by `malloc`).
2776-
2777-
.. code-block:: c
2778-
2779-
void test() {
2780-
int a, b, c[10], d[10];
2781-
int x = &c[3] - &c[1];
2782-
x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays
2783-
x = (&a + 1) - &a;
2784-
x = &b - &a; // warn: 'a' and 'b' are different variables
2785-
}
2786-
2787-
struct S {
2788-
int x[10];
2789-
int y[10];
2790-
};
2791-
2792-
void test1() {
2793-
struct S a[10];
2794-
struct S b;
2795-
int d = &a[4] - &a[6];
2796-
d = &a[0].x[3] - &a[0].x[1];
2797-
d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects
2798-
d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object
2799-
d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it
2800-
}
2801-
2802-
There may be existing applications that use code like above for calculating
2803-
offsets of members in a structure, using pointer subtractions. This is still
2804-
undefined behavior according to the standard and code like this can be replaced
2805-
with the `offsetof` macro.
2806-
28072807
.. _alpha-core-StackAddressAsyncEscape:
28082808
28092809
alpha.core.StackAddressAsyncEscape (ObjC)

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,11 +290,6 @@ def PointerArithChecker : Checker<"PointerArithm">,
290290
"elements">,
291291
Documentation<HasDocumentation>;
292292

293-
def PointerSubChecker : Checker<"PointerSub">,
294-
HelpText<"Check for pointer subtractions on two pointers pointing to "
295-
"different memory chunks">,
296-
Documentation<HasDocumentation>;
297-
298293
def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">,
299294
HelpText<"Check for division by variable that is later compared against 0. "
300295
"Either the comparison is useless or there is division by zero.">,
@@ -1003,6 +998,11 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">,
1003998
HelpText<"Warn on mmap() calls with both writable and executable access">,
1004999
Documentation<HasDocumentation>;
10051000

1001+
def PointerSubChecker : Checker<"PointerSub">,
1002+
HelpText<"Check for pointer subtractions on two pointers pointing to "
1003+
"different memory chunks">,
1004+
Documentation<HasDocumentation>;
1005+
10061006
def PutenvStackArray : Checker<"PutenvStackArray">,
10071007
HelpText<"Finds calls to the function 'putenv' which pass a pointer to "
10081008
"an automatic (stack-allocated) array as the argument.">,

clang/test/Analysis/casts.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ void locAsIntegerCasts(void *p) {
129129
}
130130

131131
void multiDimensionalArrayPointerCasts(void) {
132-
static int x[10][10]; // expected-note2{{Array at the right-hand side of subtraction}}
132+
static int x[10][10];
133133
int *y1 = &(x[3][5]);
134134
char *z = ((char *) y1) + 2;
135135
int *y2 = (int *)(z - 2);
@@ -138,9 +138,7 @@ void multiDimensionalArrayPointerCasts(void) {
138138
clang_analyzer_eval(y1 == y2); // expected-warning{{TRUE}}
139139

140140
// FIXME: should be FALSE (i.e. equal pointers).
141-
// FIXME: pointer subtraction warning might be incorrect
142141
clang_analyzer_eval(y1 - y2); // expected-warning{{UNKNOWN}}
143-
// expected-warning@-1{{Subtraction of two pointers that do not point into the same array is undefined behavior}}
144142
// FIXME: should be TRUE (i.e. same symbol).
145143
clang_analyzer_eval(*y1 == *y2); // expected-warning{{UNKNOWN}}
146144

@@ -149,9 +147,7 @@ void multiDimensionalArrayPointerCasts(void) {
149147
clang_analyzer_eval(y1 == y3); // expected-warning{{TRUE}}
150148

151149
// FIXME: should be FALSE (i.e. equal pointers).
152-
// FIXME: pointer subtraction warning might be incorrect
153150
clang_analyzer_eval(y1 - y3); // expected-warning{{UNKNOWN}}
154-
// expected-warning@-1{{Subtraction of two pointers that do not point into the same array is undefined behavior}}
155151
// FIXME: should be TRUE (i.e. same symbol).
156152
clang_analyzer_eval(*y1 == *y3); // expected-warning{{UNKNOWN}}
157153

clang/test/Analysis/pointer-sub-notes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.PointerSub -analyzer-output=text -verify %s
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=security.PointerSub -analyzer-output=text -verify %s
22

33
void different_1() {
44
int a[3]; // expected-note{{Array at the left-hand side of subtraction}}

clang/test/Analysis/pointer-sub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.PointerSub -analyzer-output=text-minimal -verify %s
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=security.PointerSub -analyzer-output=text-minimal -verify %s
22

33
void f1(void) {
44
int x, y, z[10];

0 commit comments

Comments
 (0)