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