xref: /llvm-project/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-warnings.cpp (revision 700baeb765cfe8628eb68bc24319b3db0209dd84)
1 // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions -verify %s
2 
3 namespace std {
4   class type_info { };
5 }
6 
local_assign_both_span()7 void local_assign_both_span() {
8   int tmp;
9   int* p = new int[10]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' to 'std::span' to propagate bounds information between them}}
10   tmp = p[4];  // expected-note{{used in buffer access here}}
11 
12   int* q = new int[10];  // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p' to 'std::span' to propagate bounds information between them}}
13   tmp = q[4];  // expected-note{{used in buffer access here}}
14 
15   q = p;
16 }
17 
local_assign_rhs_span()18 void local_assign_rhs_span() {
19   int tmp;
20   int* p = new int[10];
21   int* q = new int[10];  // expected-warning{{'q' is an unsafe pointer used for buffer access}}
22   tmp = q[4];  // expected-note{{used in buffer access here}}
23   p = q;  // FIXME: we do not fix `p = q` here as the `.data()` fix-it is not generally correct
24 }
25 
local_assign_no_span()26 void local_assign_no_span() {
27   int tmp;
28   int* p = new int[10];
29   int* q = new int[10];
30   p = q;
31 }
32 
local_assign_lhs_span()33 void local_assign_lhs_span() {
34   int tmp;
35   int* p = new int[10];  // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' to 'std::span' to propagate bounds information between them}}
36   tmp = p[4];  // expected-note{{used in buffer access here}}
37   int* q = new int[10];
38 
39   p = q;
40 }
41 
lhs_span_multi_assign()42 void lhs_span_multi_assign() {
43   int *a = new int[2];
44   int *b = a;
45   int *c = b;
46   int *d = c;  // expected-warning{{'d' is an unsafe pointer used for buffer access}} expected-note{{change type of 'd' to 'std::span' to preserve bounds information, and change 'c', 'b', and 'a' to 'std::span' to propagate bounds information between them}}
47   int tmp = d[2];  // expected-note{{used in buffer access here}}
48 }
49 
rhs_span()50 void rhs_span() {
51   int *x = new int[3];
52   int *y;  // expected-warning{{'y' is an unsafe pointer used for buffer access}}
53   y[5] = 10;  // expected-note{{used in buffer access here}}
54 
55   x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
56 }
57 
rhs_span1()58 void rhs_span1() {
59   int *q = new int[12];
60   int *p = q;  // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}
61   p[5] = 10;  // expected-note{{used in buffer access here}}
62   int *r = q;  // expected-warning{{'r' is an unsafe pointer used for buffer access}} expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p' and 'q' to 'std::span' to propagate bounds information between them}}
63   r[10] = 5;  // expected-note{{used in buffer access here}}
64 }
65 
rhs_span2()66 void rhs_span2() {
67   int *q = new int[6];
68   int *p = q; // expected-warning{{'p' is an unsafe pointer used for buffer access}}
69   p[5] = 10;  // expected-note{{used in buffer access here}}
70   int *r = q; // FIXME: we do not fix `int *r = q` here as the `.data()` fix-it is not generally correct
71 }
72 
test_grouping()73 void test_grouping() {
74   int *z = new int[8];
75   int tmp;
76   int *y = new int[10];  // expected-warning{{'y' is an unsafe pointer used for buffer access}}
77   tmp = y[5]; // expected-note{{used in buffer access here}}
78 
79   int *x = new int[10];
80   x = y;      // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
81 
82   int *w = z;
83 }
84 
test_grouping1()85 void test_grouping1() {
86   int tmp;
87   int *y = new int[10];  // expected-warning{{'y' is an unsafe pointer used for buffer access}}
88   tmp = y[5];  // expected-note{{used in buffer access here}}
89   int *x = new int[10];
90   x = y;       // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
91 
92   int *w = new int[10];  // expected-warning{{'w' is an unsafe pointer used for buffer access}}
93   tmp = w[5];  // expected-note{{used in buffer access here}}
94   int *z = new int[10];
95   z = w;       // FIXME: we do not fix `z = w` here as the `.data()` fix-it is not generally correct
96 }
97 
foo1a()98 void foo1a() {
99   int *r = new int[7];
100   int *p = new int[4];  // expected-warning{{'p' is an unsafe pointer used for buffer access}}
101   p = r;
102   int tmp = p[9];  // expected-note{{used in buffer access here}}
103   int *q;
104   q = r;  // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct
105 }
106 
foo1b()107 void foo1b() {
108   int *r = new int[7];
109   int *p = new int[4];  // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'r' and 'q' to 'std::span' to propagate bounds information between them}}
110   p = r;
111   int tmp = p[9];  // expected-note{{used in buffer access here}}
112   int *q;  // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p' and 'r' to 'std::span' to propagate bounds information between them}}
113   q = r;
114   tmp = q[9];  // expected-note{{used in buffer access here}}
115 }
116 
foo1c()117 void foo1c() {
118   int *r = new int[7];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
119   int *p = new int[4];
120   p = r;   // FIXME: we do not fix `p = r` here as the `.data()` fix-it is not generally correct
121   int tmp = r[9];  // expected-note{{used in buffer access here}}
122   int *q;  // expected-warning{{'q' is an unsafe pointer used for buffer access}}
123   q = r;   // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct
124   tmp = q[9];  // expected-note{{used in buffer access here}}
125 }
126 
foo2a()127 void foo2a() {
128   int *r = new int[7];
129   int *p = new int[5];  // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}
130   int *q = new int[4];
131   p = q;
132   int tmp = p[8];  // expected-note{{used in buffer access here}}
133   q = r;
134 }
135 
foo2b()136 void foo2b() {
137   int *r = new int[7];
138   int *p = new int[5];
139   int *q = new int[4];  // expected-warning{{'q' is an unsafe pointer used for buffer access}}
140   p = q;           // FIXME: we do not fix `p = q` here as the `.data()` fix-it is not generally correct
141   int tmp = q[8];  // expected-note{{used in buffer access here}}
142   q = r;
143 }
144 
foo2c()145 void foo2c() {
146   int *r = new int[7];
147   int *p = new int[5];  // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}
148   int *q = new int[4];  // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p' and 'r' to 'std::span' to propagate bounds information between them}}
149   p = q;
150   int tmp = p[8];  // expected-note{{used in buffer access here}}
151   q = r;
152   tmp = q[8];  // expected-note{{used in buffer access here}}
153 }
154 
foo3a()155 void foo3a() {
156   int *r = new int[7];
157   int *p = new int[5];  // expected-warning{{'p' is an unsafe pointer used for buffer access}}
158   int *q = new int[4];
159   q = p;           // FIXME: we do not fix `q = p` here as the `.data()` fix-it is not generally correct
160   int tmp = p[8];  // expected-note{{used in buffer access here}}
161   q = r;
162 }
163 
foo3b()164 void foo3b() {
165   int *r = new int[7];
166   int *p = new int[5];
167   int *q = new int[4];  // expected-warning{{'q' is an unsafe pointer used for buffer access}} //expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' and 'p' to 'std::span' to propagate bounds information between them}}
168   q = p;
169   int tmp = q[8];  // expected-note{{used in buffer access here}}
170   q = r;
171 }
172 
test_crash()173 void test_crash() {
174   int *r = new int[8];
175   int *q = r;
176   int *p;  // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}
177   p = q;
178   int tmp = p[9];  // expected-note{{used in buffer access here}}
179 }
180 
foo_uuc()181 void foo_uuc() {
182   int *ptr;
183   int *local;  // expected-warning{{'local' is an unsafe pointer used for buffer access}}
184   local = ptr;
185   local++;  // expected-note{{used in pointer arithmetic here}}
186 
187   (local = ptr) += 5;  // expected-warning{{unsafe pointer arithmetic}}
188 }
189 
check_rhs_fix()190 void check_rhs_fix() {
191   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}  // expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'x' to 'std::span' to propagate bounds information between them}}
192   int *x;
193   r[7] = 9;  // expected-note{{used in buffer access here}}
194   r = x;
195 }
196 
check_rhs_nofix()197 void check_rhs_nofix() {
198   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
199   int *x;  // expected-warning{{'x' is an unsafe pointer used for buffer access}}
200   r[7] = 9;  // expected-note{{used in buffer access here}}
201   r = x;
202   x++;  // expected-note{{used in pointer arithmetic here}}
203 }
204 
check_rhs_nofix_order()205 void check_rhs_nofix_order() {
206   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
207   int *x;  // expected-warning{{'x' is an unsafe pointer used for buffer access}}
208   x++;  // expected-note{{used in pointer arithmetic here}}
209   r[7] = 9;  // expected-note{{used in buffer access here}}
210   r = x;
211 }
212 
check_rhs_nofix_order1()213 void check_rhs_nofix_order1() {
214   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
215   r[7] = 9;  // expected-note{{used in buffer access here}}
216   int *x;  // expected-warning{{'x' is an unsafe pointer used for buffer access}}
217   x++;  // expected-note{{used in pointer arithmetic here}}
218   r = x;
219 }
220 
check_rhs_nofix_order2()221 void check_rhs_nofix_order2() {
222   int *x;  // expected-warning{{'x' is an unsafe pointer used for buffer access}}
223   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
224   r[7] = 9;  // expected-note{{used in buffer access here}}
225   x++;  // expected-note{{used in pointer arithmetic here}}
226   r = x;
227 }
228 
check_rhs_nofix_order3()229 void check_rhs_nofix_order3() {
230   int *x;  // expected-warning{{'x' is an unsafe pointer used for buffer access}}
231   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
232   r = x;
233   r[7] = 9;  // expected-note{{used in buffer access here}}
234   x++;  // expected-note{{used in pointer arithmetic here}}
235 }
236 
check_rhs_nofix_order4()237 void check_rhs_nofix_order4() {
238   int *x;  // expected-warning{{'x' is an unsafe pointer used for buffer access}}
239   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
240   r[7] = 9;  // expected-note{{used in buffer access here}}
241   r = x;
242   x++;  // expected-note{{used in pointer arithmetic here}}
243 }
244 
no_unhandled_lhs()245 void no_unhandled_lhs() {
246   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}  // expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'x' to 'std::span' to propagate bounds information between them}}
247   r[7] = 9;  // expected-note{{used in buffer access here}}
248   int *x;
249   r = x;
250 }
251 
unhandled_lhs()252 const std::type_info unhandled_lhs() {
253   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
254   r[7] = 9;  // expected-note{{used in buffer access here}}
255   int *x;
256   r = x;
257   return typeid(*r);
258 }
259 
unhandled_rhs()260 const std::type_info unhandled_rhs() {
261   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
262   r[7] = 9;  // expected-note{{used in buffer access here}}
263   int *x;
264   r = x;
265   return typeid(*x);
266 }
267 
test_negative_index()268 void test_negative_index() {
269   int *x = new int[4];  // expected-warning{{'x' is an unsafe pointer used for buffer access}}
270   int *p;  // expected-warning{{'p' is an unsafe pointer used for buffer access}}
271   p = &x[1];  // expected-note{{used in buffer access here}}
272   p[-1] = 9;  // expected-note{{used in buffer access here}}
273 }
274 
test_unfixable()275 void test_unfixable() {
276   int *r = new int[8];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
277   int *x;  // expected-warning{{'x' is an unsafe pointer used for buffer access}}
278   x[7] = 9;  // expected-note{{used in buffer access here}}
279   r = x;
280   r++;  // expected-note{{used in pointer arithmetic here}}
281 }
282 
test_cyclic_deps()283 void test_cyclic_deps() {
284   int *r = new int[10];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}  expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p' and 'q' to 'std::span' to propagate bounds information between them}}
285   int *q;
286   q = r;
287   int *p;
288   p = q;
289   r[3] = 9; // expected-note{{used in buffer access here}}
290   r = p;
291 }
292 
test_cyclic_deps_a()293 void test_cyclic_deps_a() {
294   int *r = new int[10];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}
295   int *q;
296   q = r;
297   int *p;  // expected-warning{{'p' is an unsafe pointer used for buffer access}}
298   p = q;
299   r[3] = 9; // expected-note{{used in buffer access here}}
300   r = p;
301   p++;  // expected-note{{used in pointer arithmetic here}}
302 }
303 
test_cyclic_deps1()304 void test_cyclic_deps1() {
305   int *r = new int[10];
306   int *q;
307   q = r;
308   int *p;  // expected-warning{{'p' is an unsafe pointer used for buffer access}}  expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}
309   p = q;
310   p[3] = 9; // expected-note{{used in buffer access here}}
311   r = p;
312 }
313 
test_cyclic_deps2()314 void test_cyclic_deps2() {
315   int *r = new int[10];
316   int *q;  // expected-warning{{'q' is an unsafe pointer used for buffer access}}  expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' and 'p' to 'std::span' to propagate bounds information between them}}
317   q = r;
318   int *p;
319   p = q;
320   q[3] = 9; // expected-note{{used in buffer access here}}
321   r = p;
322 }
323 
test_cyclic_deps3()324 void test_cyclic_deps3() {
325   int *r = new int[10];
326   int *q;  // expected-warning{{'q' is an unsafe pointer used for buffer access}}  expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' and 'p' to 'std::span' to propagate bounds information between them}}
327   q = r;
328   int *p;  // expected-warning{{'p' is an unsafe pointer used for buffer access}}  expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to 'std::span' to propagate bounds information between them}}
329   p = q;
330   q[3] = 9; // expected-note{{used in buffer access here}}
331   p[4] = 7; // expected-note{{used in buffer access here}}
332   r = p;
333 }
334 
test_cyclic_deps4()335 void test_cyclic_deps4() {
336   int *r = new int[10];  // expected-warning{{'r' is an unsafe pointer used for buffer access}}  expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p' and 'q' to 'std::span' to propagate bounds information between them}}
337   int *q;  // expected-warning{{'q' is an unsafe pointer used for buffer access}}  expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' and 'p' to 'std::span' to propagate bounds information between them}}
338   q = r;
339   int *p;  // expected-warning{{'p' is an unsafe pointer used for buffer access}}  expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'r' and 'q' to 'std::span' to propagate bounds information between them}}
340   p = q;
341   q[3] = 9; // expected-note{{used in buffer access here}}
342   p[4] = 7; // expected-note{{used in buffer access here}}
343   r[1] = 5; // expected-note{{used in buffer access here}}
344   r = p;
345 }
346