[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / warn-unsafe-buffer-usage-multi-decl-warnings.cpp
blob917aa9520347d3416b4c211518a65948cfd6a751
1 // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions -verify %s
3 namespace std {
4 class type_info { };
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}}
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}}
15 q = p;
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
26 void local_assign_no_span() {
27 int tmp;
28 int* p = new int[10];
29 int* q = new int[10];
30 p = q;
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];
39 p = q;
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}}
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}}
55 x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
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}}
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
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}}
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
82 int *w = z;
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
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
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
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}}
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}}
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;
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;
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}}
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;
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;
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}}
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}}
187 (local = ptr) += 5; // expected-warning{{unsafe pointer arithmetic}}
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;
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}}
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;
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;
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;
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}}
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}}
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;
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);
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);
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}}
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}}
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;
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}}
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;
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;
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;
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;