1*89a1d03eSRichard // RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
2*89a1d03eSRichard 
3*89a1d03eSRichard enum E {
4*89a1d03eSRichard   ENUM_LITERAL = 1
5*89a1d03eSRichard };
6*89a1d03eSRichard 
7*89a1d03eSRichard int i = 4;
8*89a1d03eSRichard int j = 1;
9*89a1d03eSRichard int *p = 0;
10*89a1d03eSRichard int *q = 0;
11*89a1d03eSRichard 
fail()12*89a1d03eSRichard void fail() {
13*89a1d03eSRichard   q = p + 4;
14*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
15*89a1d03eSRichard   p = q + i;
16*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
17*89a1d03eSRichard   p = q + ENUM_LITERAL;
18*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
19*89a1d03eSRichard 
20*89a1d03eSRichard   q = p - 1;
21*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
22*89a1d03eSRichard   p = q - i;
23*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
24*89a1d03eSRichard   p = q - ENUM_LITERAL;
25*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
26*89a1d03eSRichard 
27*89a1d03eSRichard   p += 4;
28*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
29*89a1d03eSRichard   p += i;
30*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
31*89a1d03eSRichard   p += ENUM_LITERAL;
32*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
33*89a1d03eSRichard 
34*89a1d03eSRichard   q -= 1;
35*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
36*89a1d03eSRichard   q -= i;
37*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
38*89a1d03eSRichard   q -= ENUM_LITERAL;
39*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
40*89a1d03eSRichard 
41*89a1d03eSRichard   p++;
42*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
43*89a1d03eSRichard   ++p;
44*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
45*89a1d03eSRichard 
46*89a1d03eSRichard   p--;
47*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
48*89a1d03eSRichard   --p;
49*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
50*89a1d03eSRichard 
51*89a1d03eSRichard   i = p[1];
52*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
53*89a1d03eSRichard }
54*89a1d03eSRichard 
55*89a1d03eSRichard struct S {
56*89a1d03eSRichard   operator int() const;
57*89a1d03eSRichard };
58*89a1d03eSRichard 
f(S & s)59*89a1d03eSRichard void f(S &s) {
60*89a1d03eSRichard   int *i;
61*89a1d03eSRichard   i = i + s;
62*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
63*89a1d03eSRichard }
64*89a1d03eSRichard 
f2(int i[])65*89a1d03eSRichard void f2(int i[]) {
66*89a1d03eSRichard   i[1] = 0;
67*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
68*89a1d03eSRichard }
69*89a1d03eSRichard 
okay()70*89a1d03eSRichard void okay() {
71*89a1d03eSRichard   int a[3];
72*89a1d03eSRichard   i = a[2]; // OK, access to array
73*89a1d03eSRichard 
74*89a1d03eSRichard   p = q;
75*89a1d03eSRichard   p = &i;
76*89a1d03eSRichard 
77*89a1d03eSRichard   i++;
78*89a1d03eSRichard   ++i;
79*89a1d03eSRichard   i--;
80*89a1d03eSRichard   --i;
81*89a1d03eSRichard   i += 1;
82*89a1d03eSRichard   i -= 1;
83*89a1d03eSRichard   i = j + 1;
84*89a1d03eSRichard   i = j - 1;
85*89a1d03eSRichard 
86*89a1d03eSRichard   auto diff = p - q; // OK, result is arithmetic
87*89a1d03eSRichard 
88*89a1d03eSRichard   for(int ii : a) ; // OK, pointer arithmetic generated by compiler
89*89a1d03eSRichard }
90