xref: /llvm-project/clang/test/Analysis/uninit-structured-binding-array.cpp (revision 8a13326d184c2829a51d7c00f467ded06412f858)
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
2 
3 void clang_analyzer_eval(bool);
4 
array_value_a(void)5 void array_value_a(void) {
6   int arr[2];
7   auto [a, b] = arr;
8   arr[0] = 0;
9 
10   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
11 }
12 
array_value_b(void)13 void array_value_b(void) {
14   int arr[] = {1, 2};
15   auto [a, b] = arr;
16 
17   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
18   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
19 
20   int x = a; // no-warning
21 }
22 
array_value_c(void)23 void array_value_c(void) {
24   int arr[3];
25 
26   arr[1] = 1;
27 
28   auto [a, b, c] = arr;
29 
30   clang_analyzer_eval(b == arr[1]); // expected-warning{{TRUE}}
31 
32   int y = b; // no-warning
33   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
34 }
35 
array_value_d(void)36 void array_value_d(void) {
37   int arr[3];
38 
39   arr[1] = 1;
40 
41   auto [a, b, c] = arr;
42 
43   clang_analyzer_eval(b == arr[1]); // expected-warning{{TRUE}}
44 
45   int y = b; // no-warning
46   int x = c; // expected-warning{{Assigned value is garbage or undefined}}
47 }
48 
array_value_e(void)49 void array_value_e(void) {
50   int uninit[2];
51   int init[2] = {0};
52 
53   uninit[0] = init[0];
54 
55   auto [i, j] = init;
56 
57   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
58   clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
59 
60   int a = i; // no-warning
61   int b = j; // no-warning
62 }
63 
array_value_f(void)64 void array_value_f(void) {
65   int uninit[2];
66   int init[2] = {0};
67 
68   uninit[0] = init[0];
69 
70   auto [i, j] = uninit;
71 
72   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
73 
74   int a = i; // no-warning
75   int b = j; // expected-warning{{Assigned value is garbage or undefined}}
76 }
77 
array_lref_a(void)78 void array_lref_a(void) {
79   int arr[2];
80   auto &[a, b] = arr;
81   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
82 }
83 
array_lref_b(void)84 void array_lref_b(void) {
85   int arr[] = {1, 2};
86   auto &[a, b] = arr;
87 
88   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
89   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
90 
91   int x = a; // no-warning
92 }
93 
array_lref_c(void)94 void array_lref_c(void) {
95   int arr[2];
96   auto &[a, b] = arr;
97 
98   arr[0] = 1;
99 
100   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
101 
102   int x = a; // no-warning
103   int y = b; // expected-warning{{Assigned value is garbage or undefined}}
104 }
105 
array_lref_d(void)106 void array_lref_d(void) {
107   int arr[3];
108 
109   arr[1] = 1;
110 
111   auto &[a, b, c] = arr;
112 
113   clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
114 
115   int y = b; // no-warning
116   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
117 }
118 
array_lref_e(void)119 void array_lref_e(void) {
120   int arr[3];
121 
122   arr[1] = 1;
123 
124   auto &[a, b, c] = arr;
125 
126   clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
127 
128   int y = b; // no-warning
129   int x = c; // expected-warning{{Assigned value is garbage or undefined}}
130 }
131 
array_lref_f(void)132 void array_lref_f(void) {
133   int uninit[2];
134   int init[2] = {0};
135 
136   uninit[0] = init[0];
137 
138   auto &[i, j] = init;
139 
140   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
141   clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
142 
143   int a = i; // no-warning
144   int b = j; // no-warning
145 }
146 
array_lref_g(void)147 void array_lref_g(void) {
148   int uninit[2];
149   int init[2] = {0};
150 
151   uninit[0] = init[0];
152 
153   auto &[i, j] = uninit;
154 
155   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
156 
157   int a = i; // no-warning
158   int b = j; // expected-warning{{Assigned value is garbage or undefined}}
159 }
160 
array_rref_a(void)161 void array_rref_a(void) {
162   int arr[2];
163   auto &&[a, b] = arr;
164   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
165 }
166 
array_rref_b(void)167 void array_rref_b(void) {
168   int arr[] = {1, 2};
169   auto &&[a, b] = arr;
170 
171   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
172   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
173 
174   int x = a; // no-warning
175 }
176 
array_rref_c(void)177 void array_rref_c(void) {
178   int arr[2];
179   auto &&[a, b] = arr;
180 
181   arr[0] = 1;
182 
183   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
184 
185   int x = a; // no-warning
186   int y = b; // expected-warning{{Assigned value is garbage or undefined}}
187 }
188 
array_rref_d(void)189 void array_rref_d(void) {
190   int arr[3];
191 
192   arr[1] = 1;
193 
194   auto &&[a, b, c] = arr;
195 
196   clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
197 
198   int y = b; // no-warning
199   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
200 }
201 
array_rref_e(void)202 void array_rref_e(void) {
203   int arr[3];
204 
205   arr[1] = 1;
206 
207   auto &&[a, b, c] = arr;
208 
209   clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
210 
211   int y = b; // no-warning
212   int x = c; // expected-warning{{Assigned value is garbage or undefined}}
213 }
214 
array_rref_f(void)215 void array_rref_f(void) {
216   int uninit[2];
217   int init[2] = {0};
218 
219   uninit[0] = init[0];
220 
221   auto &&[i, j] = init;
222 
223   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
224   clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
225 
226   int a = i; // no-warning
227   int b = j; // no-warning
228 }
229 
array_rref_g(void)230 void array_rref_g(void) {
231   int uninit[2];
232   int init[2] = {0};
233 
234   uninit[0] = init[0];
235 
236   auto &&[i, j] = uninit;
237 
238   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
239 
240   int a = i; // no-warning
241   int b = j; // expected-warning{{Assigned value is garbage or undefined}}
242 }
243 
array_change_a(void)244 void array_change_a(void) {
245   int arr[] = {1, 2};
246 
247   auto [a, b] = arr;
248 
249   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
250   a = 3;
251   clang_analyzer_eval(a == 3); // expected-warning{{TRUE}}
252 
253   clang_analyzer_eval(arr[0] == 1); // expected-warning{{TRUE}}
254   clang_analyzer_eval(arr[1] == 2); // expected-warning{{TRUE}}
255 
256   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
257 }
258 
array_change_b(void)259 void array_change_b(void) {
260   int arr[] = {1, 2};
261 
262   auto &[a, b] = arr;
263 
264   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
265   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
266 
267   a = 3;
268   clang_analyzer_eval(a == 3); // expected-warning{{TRUE}}
269 
270   clang_analyzer_eval(arr[0] == 3); // expected-warning{{TRUE}}
271   clang_analyzer_eval(arr[1] == 2); // expected-warning{{TRUE}}
272 }
273 
array_small_a(void)274 void array_small_a(void) {
275   int arr[5];
276 
277   auto [a, b, c, d, e] = arr;
278 
279   int x = e; // expected-warning{{Assigned value is garbage or undefined}}
280 }
281 
array_big_a(void)282 void array_big_a(void) {
283   int arr[6];
284 
285   auto [a, b, c, d, e, f] = arr;
286 
287   // FIXME: These will be Undefined when we handle reading Undefined values from lazyCompoundVal.
288   clang_analyzer_eval(a == 1); // expected-warning{{UNKNOWN}}
289   clang_analyzer_eval(b == 2); // expected-warning{{UNKNOWN}}
290   clang_analyzer_eval(c == 3); // expected-warning{{UNKNOWN}}
291   clang_analyzer_eval(d == 4); // expected-warning{{UNKNOWN}}
292   clang_analyzer_eval(e == 5); // expected-warning{{UNKNOWN}}
293   clang_analyzer_eval(f == 6); // expected-warning{{UNKNOWN}}
294 }
295 
296 struct S {
297   int a = 1;
298   int b = 2;
299 };
300 
non_pod_val(void)301 void non_pod_val(void) {
302   S arr[2];
303 
304   auto [x, y] = arr;
305 
306   clang_analyzer_eval(x.a == 1); // expected-warning{{TRUE}}
307   clang_analyzer_eval(x.b == 2); // expected-warning{{TRUE}}
308 
309   clang_analyzer_eval(y.a == 1); // expected-warning{{TRUE}}
310   clang_analyzer_eval(y.b == 2); // expected-warning{{TRUE}}
311 }
312 
non_pod_val_syntax_2(void)313 void non_pod_val_syntax_2(void) {
314   S arr[2];
315 
316   auto [x, y](arr);
317 
318   clang_analyzer_eval(x.a == 1); // expected-warning{{TRUE}}
319   clang_analyzer_eval(x.b == 2); // expected-warning{{TRUE}}
320 
321   clang_analyzer_eval(y.a == 1); // expected-warning{{TRUE}}
322   clang_analyzer_eval(y.b == 2); // expected-warning{{TRUE}}
323 }
324 
non_pod_lref(void)325 void non_pod_lref(void) {
326   S arr[2];
327 
328   auto &[x, y] = arr;
329 
330   clang_analyzer_eval(x.a == 1); // expected-warning{{TRUE}}
331   clang_analyzer_eval(x.b == 2); // expected-warning{{TRUE}}
332 
333   clang_analyzer_eval(y.a == 1); // expected-warning{{TRUE}}
334   clang_analyzer_eval(y.b == 2); // expected-warning{{TRUE}}
335 }
336 
non_pod_rref(void)337 void non_pod_rref(void) {
338   S arr[2];
339 
340   auto &&[x, y] = arr;
341 
342   clang_analyzer_eval(x.a == 1); // expected-warning{{TRUE}}
343   clang_analyzer_eval(x.b == 2); // expected-warning{{TRUE}}
344 
345   clang_analyzer_eval(y.a == 1); // expected-warning{{TRUE}}
346   clang_analyzer_eval(y.b == 2); // expected-warning{{TRUE}}
347 }
348 
349 struct SUD {
350   inline static int c = 0;
351 
352   int a = 1;
353   int b = 2;
354 
SUDSUD355   SUD() { ++c; };
356 
SUDSUD357   SUD(const SUD &copy) {
358     a = copy.a + 1;
359     b = copy.b + 1;
360   }
361 };
362 
non_pod_user_defined_val(void)363 void non_pod_user_defined_val(void) {
364   SUD arr[2];
365 
366   auto [x, y] = arr;
367 
368   clang_analyzer_eval(x.a == 2); // expected-warning{{TRUE}}
369   clang_analyzer_eval(x.b == 3); // expected-warning{{TRUE}}
370 
371   clang_analyzer_eval(y.a == 2); // expected-warning{{TRUE}}
372   clang_analyzer_eval(y.b == 3); // expected-warning{{TRUE}}
373 }
374 
non_pod_user_defined_val_syntax_2(void)375 void non_pod_user_defined_val_syntax_2(void) {
376   SUD::c = 0;
377   SUD arr[2];
378 
379   auto [x, y](arr);
380 
381   clang_analyzer_eval(SUD::c == 2); // expected-warning{{TRUE}}
382 
383   clang_analyzer_eval(x.a == 2); // expected-warning{{TRUE}}
384   clang_analyzer_eval(x.b == 3); // expected-warning{{TRUE}}
385 
386   clang_analyzer_eval(y.a == 2); // expected-warning{{TRUE}}
387   clang_analyzer_eval(y.b == 3); // expected-warning{{TRUE}}
388 }
389