File: pointer-sub.c

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (122 lines) | stat: -rw-r--r-- 5,198 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.PointerSub -verify %s

void f1(void) {
  int x, y, z[10];
  int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}}
  d = z - &y; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}}
  d = &x - &x; // no-warning (subtraction of any two identical pointers is allowed)
  d = (long *)&x - (long *)&x;
  d = (&x + 1) - &x; // no-warning ('&x' is like a single-element array)
  d = &x - (&x + 1); // no-warning
  d = (&x + 0) - &x; // no-warning
  d = (&x - 1) - &x; // expected-warning{{Indexing the address of a variable with other than 1 at this place is undefined behavior}}
  d = (&x + 2) - &x; // expected-warning{{Indexing the address of a variable with other than 1 at this place is undefined behavior}}

  d = (z + 9) - z; // no-warning (pointers to same array)
  d = (z + 10) - z; // no-warning (pointer to "one after the end")
  d = (z + 11) - z; // expected-warning{{Using an array index greater than the array size at pointer subtraction is undefined behavior}}
  d = (z - 1) - z; // expected-warning{{Using a negative array index at pointer subtraction is undefined behavior}}
}

void f2(void) {
  int a[10], b[10], c; // expected-note{{Array at the left-hand side of subtraction}} \
                       // expected-note2{{Array at the right-hand side of subtraction}}
  int *p = &a[2];
  int *q = &a[8];
  int d = q - p; // no-warning (pointers into the same array)

  q = &b[3];
  d = q - p; // expected-warning{{Subtraction of two pointers that}}

  q = a + 10;
  d = q - p; // no warning (use of pointer to one after the end is allowed)
  q = a + 11;
  d = q - a; // expected-warning{{Using an array index greater than the array size at pointer subtraction is undefined behavior}}

  d = &a[4] - a; // no-warning
  d = &a[2] - p; // no-warning
  d = &c - p; // expected-warning{{Subtraction of two pointers that}}

  d = (int *)((char *)(&a[4]) + sizeof(int)) - &a[4]; // no-warning (pointers into the same array data)
  d = (int *)((char *)(&a[4]) + 1) - &a[4]; // expected-warning{{Subtraction of two pointers that}}
}

void f3(void) {
  int a[3][4]; // expected-note{{Array at the left-hand side of subtraction}} \
               // expected-note2{{Array at the right-hand side of subtraction}}
  int d;

  d = &(a[2]) - &(a[1]);
  d = a[2] - a[1]; // expected-warning{{Subtraction of two pointers that}}
  d = a[1] - a[1];
  d = &(a[1][2]) - &(a[1][0]);
  d = &(a[1][2]) - &(a[0][0]); // expected-warning{{Subtraction of two pointers that}}

  d = (int *)((char *)(&a[2][2]) + sizeof(int)) - &a[2][2]; // expected-warning{{Subtraction of two pointers that}}
  d = (int *)((char *)(&a[2][2]) + 1) - &a[2][2]; // expected-warning{{Subtraction of two pointers that}}
  d = (int (*)[4])((char *)&a[2] + sizeof(int (*)[4])) - &a[2]; // expected-warning{{Subtraction of two pointers that}}
  d = (int (*)[4])((char *)&a[2] + 1) - &a[2]; // expected-warning{{Subtraction of two pointers that}}
}

void f4(void) {
  int n = 4, m = 3;
  int a[n][m];
  int (*p)[m] = a; // p == &a[0]
  p += 1; // p == &a[1]

  // FIXME: This is a known problem with -Wpointer-arith (https://github.com/llvm/llvm-project/issues/28328)
  int d = p - a; // d == 1 // expected-warning{{subtraction of pointers to type 'int[m]' of zero size has undefined behavior}}

  // FIXME: This is a known problem with -Wpointer-arith (https://github.com/llvm/llvm-project/issues/28328)
  d = &(a[2]) - &(a[1]); // expected-warning{{subtraction of pointers to type 'int[m]' of zero size has undefined behavior}}

  d = a[2] - a[1]; // expected-warning{{Subtraction of two pointers that}}
}

typedef struct {
  int a;
  int b;
  int c[10]; // expected-note2{{Array at the right-hand side of subtraction}}
  int d[10]; // expected-note2{{Array at the left-hand side of subtraction}}
} S;

void f5(void) {
  S s;
  int y;
  int d;

  d = &s.b - &s.a; // expected-warning{{Subtraction of two pointers that}}
  d = &s.c[0] - &s.a; // expected-warning{{Subtraction of two pointers that}}
  d = &s.b - &y; // expected-warning{{Subtraction of two pointers that}}
  d = &s.c[3] - &s.c[2];
  d = &s.d[3] - &s.c[2]; // expected-warning{{Subtraction of two pointers that}}
  d = s.d - s.c; // expected-warning{{Subtraction of two pointers that}}

  S sa[10];
  d = &sa[2] - &sa[1];
  d = &sa[2].a - &sa[1].b; // expected-warning{{Subtraction of two pointers that}}
}

void f6(void) {
  long long l;
  char *a1 = (char *)&l;
  int d = a1[3] - l;

  long long la1[3]; // expected-note{{Array at the right-hand side of subtraction}}
  long long la2[3]; // expected-note{{Array at the left-hand side of subtraction}}
  char *pla1 = (char *)la1;
  char *pla2 = (char *)la2;
  d = pla1[1] - pla1[0];
  d = (long long *)&pla1[1] - &l; // expected-warning{{Subtraction of two pointers that}}
  d = &pla2[3] - &pla1[3]; // expected-warning{{Subtraction of two pointers that}}
}

void f7(int *p) {
  int a[10];
  int d = &a[10] - p; // no-warning ('p' is unknown, even if it cannot point into 'a')
}

void f8(int n) {
  int a[10];
  int d = a[n] - a[0];
}