1*8ef62808Sisuckatcs // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
2*8ef62808Sisuckatcs 
3*8ef62808Sisuckatcs void clang_analyzer_eval(bool);
4*8ef62808Sisuckatcs 
5*8ef62808Sisuckatcs void array_value_a(void) {
6*8ef62808Sisuckatcs   int arr[2];
7*8ef62808Sisuckatcs   auto [a, b] = arr;
8*8ef62808Sisuckatcs   arr[0] = 0;
9*8ef62808Sisuckatcs 
10*8ef62808Sisuckatcs   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
11*8ef62808Sisuckatcs }
12*8ef62808Sisuckatcs 
13*8ef62808Sisuckatcs void array_value_b(void) {
14*8ef62808Sisuckatcs   int arr[] = {1, 2};
15*8ef62808Sisuckatcs   auto [a, b] = arr;
16*8ef62808Sisuckatcs 
17*8ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
18*8ef62808Sisuckatcs   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
19*8ef62808Sisuckatcs 
20*8ef62808Sisuckatcs   int x = a; // no-warning
21*8ef62808Sisuckatcs }
22*8ef62808Sisuckatcs 
23*8ef62808Sisuckatcs void array_value_c(void) {
24*8ef62808Sisuckatcs   int arr[3];
25*8ef62808Sisuckatcs 
26*8ef62808Sisuckatcs   arr[1] = 1;
27*8ef62808Sisuckatcs 
28*8ef62808Sisuckatcs   auto [a, b, c] = arr;
29*8ef62808Sisuckatcs 
30*8ef62808Sisuckatcs   clang_analyzer_eval(b == arr[1]); // expected-warning{{TRUE}}
31*8ef62808Sisuckatcs 
32*8ef62808Sisuckatcs   int y = b; // no-warning
33*8ef62808Sisuckatcs   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
34*8ef62808Sisuckatcs }
35*8ef62808Sisuckatcs 
36*8ef62808Sisuckatcs void array_value_d(void) {
37*8ef62808Sisuckatcs   int arr[3];
38*8ef62808Sisuckatcs 
39*8ef62808Sisuckatcs   arr[1] = 1;
40*8ef62808Sisuckatcs 
41*8ef62808Sisuckatcs   auto [a, b, c] = arr;
42*8ef62808Sisuckatcs 
43*8ef62808Sisuckatcs   clang_analyzer_eval(b == arr[1]); // expected-warning{{TRUE}}
44*8ef62808Sisuckatcs 
45*8ef62808Sisuckatcs   int y = b; // no-warning
46*8ef62808Sisuckatcs   int x = c; // expected-warning{{Assigned value is garbage or undefined}}
47*8ef62808Sisuckatcs }
48*8ef62808Sisuckatcs 
49*8ef62808Sisuckatcs void array_value_e(void) {
50*8ef62808Sisuckatcs   int uninit[2];
51*8ef62808Sisuckatcs   int init[2] = {0};
52*8ef62808Sisuckatcs 
53*8ef62808Sisuckatcs   uninit[0] = init[0];
54*8ef62808Sisuckatcs 
55*8ef62808Sisuckatcs   auto [i, j] = init;
56*8ef62808Sisuckatcs 
57*8ef62808Sisuckatcs   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
58*8ef62808Sisuckatcs   clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
59*8ef62808Sisuckatcs 
60*8ef62808Sisuckatcs   int a = i; // no-warning
61*8ef62808Sisuckatcs   int b = j; // no-warning
62*8ef62808Sisuckatcs }
63*8ef62808Sisuckatcs 
64*8ef62808Sisuckatcs void array_value_f(void) {
65*8ef62808Sisuckatcs   int uninit[2];
66*8ef62808Sisuckatcs   int init[2] = {0};
67*8ef62808Sisuckatcs 
68*8ef62808Sisuckatcs   uninit[0] = init[0];
69*8ef62808Sisuckatcs 
70*8ef62808Sisuckatcs   auto [i, j] = uninit;
71*8ef62808Sisuckatcs 
72*8ef62808Sisuckatcs   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
73*8ef62808Sisuckatcs 
74*8ef62808Sisuckatcs   int a = i; // no-warning
75*8ef62808Sisuckatcs   int b = j; // expected-warning{{Assigned value is garbage or undefined}}
76*8ef62808Sisuckatcs }
77*8ef62808Sisuckatcs 
78*8ef62808Sisuckatcs void array_lref_a(void) {
79*8ef62808Sisuckatcs   int arr[2];
80*8ef62808Sisuckatcs   auto &[a, b] = arr;
81*8ef62808Sisuckatcs   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
82*8ef62808Sisuckatcs }
83*8ef62808Sisuckatcs 
84*8ef62808Sisuckatcs void array_lref_b(void) {
85*8ef62808Sisuckatcs   int arr[] = {1, 2};
86*8ef62808Sisuckatcs   auto &[a, b] = arr;
87*8ef62808Sisuckatcs 
88*8ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
89*8ef62808Sisuckatcs   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
90*8ef62808Sisuckatcs 
91*8ef62808Sisuckatcs   int x = a; // no-warning
92*8ef62808Sisuckatcs }
93*8ef62808Sisuckatcs 
94*8ef62808Sisuckatcs void array_lref_c(void) {
95*8ef62808Sisuckatcs   int arr[2];
96*8ef62808Sisuckatcs   auto &[a, b] = arr;
97*8ef62808Sisuckatcs 
98*8ef62808Sisuckatcs   arr[0] = 1;
99*8ef62808Sisuckatcs 
100*8ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
101*8ef62808Sisuckatcs 
102*8ef62808Sisuckatcs   int x = a; // no-warning
103*8ef62808Sisuckatcs   int y = b; // expected-warning{{Assigned value is garbage or undefined}}
104*8ef62808Sisuckatcs }
105*8ef62808Sisuckatcs 
106*8ef62808Sisuckatcs void array_lref_d(void) {
107*8ef62808Sisuckatcs   int arr[3];
108*8ef62808Sisuckatcs 
109*8ef62808Sisuckatcs   arr[1] = 1;
110*8ef62808Sisuckatcs 
111*8ef62808Sisuckatcs   auto &[a, b, c] = arr;
112*8ef62808Sisuckatcs 
113*8ef62808Sisuckatcs   clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
114*8ef62808Sisuckatcs 
115*8ef62808Sisuckatcs   int y = b; // no-warning
116*8ef62808Sisuckatcs   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
117*8ef62808Sisuckatcs }
118*8ef62808Sisuckatcs 
119*8ef62808Sisuckatcs void array_lref_e(void) {
120*8ef62808Sisuckatcs   int arr[3];
121*8ef62808Sisuckatcs 
122*8ef62808Sisuckatcs   arr[1] = 1;
123*8ef62808Sisuckatcs 
124*8ef62808Sisuckatcs   auto &[a, b, c] = arr;
125*8ef62808Sisuckatcs 
126*8ef62808Sisuckatcs   clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
127*8ef62808Sisuckatcs 
128*8ef62808Sisuckatcs   int y = b; // no-warning
129*8ef62808Sisuckatcs   int x = c; // expected-warning{{Assigned value is garbage or undefined}}
130*8ef62808Sisuckatcs }
131*8ef62808Sisuckatcs 
132*8ef62808Sisuckatcs void array_lref_f(void) {
133*8ef62808Sisuckatcs   int uninit[2];
134*8ef62808Sisuckatcs   int init[2] = {0};
135*8ef62808Sisuckatcs 
136*8ef62808Sisuckatcs   uninit[0] = init[0];
137*8ef62808Sisuckatcs 
138*8ef62808Sisuckatcs   auto &[i, j] = init;
139*8ef62808Sisuckatcs 
140*8ef62808Sisuckatcs   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
141*8ef62808Sisuckatcs   clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
142*8ef62808Sisuckatcs 
143*8ef62808Sisuckatcs   int a = i; // no-warning
144*8ef62808Sisuckatcs   int b = j; // no-warning
145*8ef62808Sisuckatcs }
146*8ef62808Sisuckatcs 
147*8ef62808Sisuckatcs void array_lref_g(void) {
148*8ef62808Sisuckatcs   int uninit[2];
149*8ef62808Sisuckatcs   int init[2] = {0};
150*8ef62808Sisuckatcs 
151*8ef62808Sisuckatcs   uninit[0] = init[0];
152*8ef62808Sisuckatcs 
153*8ef62808Sisuckatcs   auto &[i, j] = uninit;
154*8ef62808Sisuckatcs 
155*8ef62808Sisuckatcs   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
156*8ef62808Sisuckatcs 
157*8ef62808Sisuckatcs   int a = i; // no-warning
158*8ef62808Sisuckatcs   int b = j; // expected-warning{{Assigned value is garbage or undefined}}
159*8ef62808Sisuckatcs }
160*8ef62808Sisuckatcs 
161*8ef62808Sisuckatcs void array_rref_a(void) {
162*8ef62808Sisuckatcs   int arr[2];
163*8ef62808Sisuckatcs   auto &&[a, b] = arr;
164*8ef62808Sisuckatcs   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
165*8ef62808Sisuckatcs }
166*8ef62808Sisuckatcs 
167*8ef62808Sisuckatcs void array_rref_b(void) {
168*8ef62808Sisuckatcs   int arr[] = {1, 2};
169*8ef62808Sisuckatcs   auto &&[a, b] = arr;
170*8ef62808Sisuckatcs 
171*8ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
172*8ef62808Sisuckatcs   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
173*8ef62808Sisuckatcs 
174*8ef62808Sisuckatcs   int x = a; // no-warning
175*8ef62808Sisuckatcs }
176*8ef62808Sisuckatcs 
177*8ef62808Sisuckatcs void array_rref_c(void) {
178*8ef62808Sisuckatcs   int arr[2];
179*8ef62808Sisuckatcs   auto &&[a, b] = arr;
180*8ef62808Sisuckatcs 
181*8ef62808Sisuckatcs   arr[0] = 1;
182*8ef62808Sisuckatcs 
183*8ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
184*8ef62808Sisuckatcs 
185*8ef62808Sisuckatcs   int x = a; // no-warning
186*8ef62808Sisuckatcs   int y = b; // expected-warning{{Assigned value is garbage or undefined}}
187*8ef62808Sisuckatcs }
188*8ef62808Sisuckatcs 
189*8ef62808Sisuckatcs void array_rref_d(void) {
190*8ef62808Sisuckatcs   int arr[3];
191*8ef62808Sisuckatcs 
192*8ef62808Sisuckatcs   arr[1] = 1;
193*8ef62808Sisuckatcs 
194*8ef62808Sisuckatcs   auto &&[a, b, c] = arr;
195*8ef62808Sisuckatcs 
196*8ef62808Sisuckatcs   clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
197*8ef62808Sisuckatcs 
198*8ef62808Sisuckatcs   int y = b; // no-warning
199*8ef62808Sisuckatcs   int x = a; // expected-warning{{Assigned value is garbage or undefined}}
200*8ef62808Sisuckatcs }
201*8ef62808Sisuckatcs 
202*8ef62808Sisuckatcs void array_rref_e(void) {
203*8ef62808Sisuckatcs   int arr[3];
204*8ef62808Sisuckatcs 
205*8ef62808Sisuckatcs   arr[1] = 1;
206*8ef62808Sisuckatcs 
207*8ef62808Sisuckatcs   auto &&[a, b, c] = arr;
208*8ef62808Sisuckatcs 
209*8ef62808Sisuckatcs   clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
210*8ef62808Sisuckatcs 
211*8ef62808Sisuckatcs   int y = b; // no-warning
212*8ef62808Sisuckatcs   int x = c; // expected-warning{{Assigned value is garbage or undefined}}
213*8ef62808Sisuckatcs }
214*8ef62808Sisuckatcs 
215*8ef62808Sisuckatcs void array_rref_f(void) {
216*8ef62808Sisuckatcs   int uninit[2];
217*8ef62808Sisuckatcs   int init[2] = {0};
218*8ef62808Sisuckatcs 
219*8ef62808Sisuckatcs   uninit[0] = init[0];
220*8ef62808Sisuckatcs 
221*8ef62808Sisuckatcs   auto &&[i, j] = init;
222*8ef62808Sisuckatcs 
223*8ef62808Sisuckatcs   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
224*8ef62808Sisuckatcs   clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
225*8ef62808Sisuckatcs 
226*8ef62808Sisuckatcs   int a = i; // no-warning
227*8ef62808Sisuckatcs   int b = j; // no-warning
228*8ef62808Sisuckatcs }
229*8ef62808Sisuckatcs 
230*8ef62808Sisuckatcs void array_rref_g(void) {
231*8ef62808Sisuckatcs   int uninit[2];
232*8ef62808Sisuckatcs   int init[2] = {0};
233*8ef62808Sisuckatcs 
234*8ef62808Sisuckatcs   uninit[0] = init[0];
235*8ef62808Sisuckatcs 
236*8ef62808Sisuckatcs   auto &&[i, j] = uninit;
237*8ef62808Sisuckatcs 
238*8ef62808Sisuckatcs   clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
239*8ef62808Sisuckatcs 
240*8ef62808Sisuckatcs   int a = i; // no-warning
241*8ef62808Sisuckatcs   int b = j; // expected-warning{{Assigned value is garbage or undefined}}
242*8ef62808Sisuckatcs }
243*8ef62808Sisuckatcs 
244*8ef62808Sisuckatcs void array_change_a(void) {
245*8ef62808Sisuckatcs   int arr[] = {1, 2};
246*8ef62808Sisuckatcs 
247*8ef62808Sisuckatcs   auto [a, b] = arr;
248*8ef62808Sisuckatcs 
249*8ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
250*8ef62808Sisuckatcs   a = 3;
251*8ef62808Sisuckatcs   clang_analyzer_eval(a == 3); // expected-warning{{TRUE}}
252*8ef62808Sisuckatcs 
253*8ef62808Sisuckatcs   clang_analyzer_eval(arr[0] == 1); // expected-warning{{TRUE}}
254*8ef62808Sisuckatcs   clang_analyzer_eval(arr[1] == 2); // expected-warning{{TRUE}}
255*8ef62808Sisuckatcs 
256*8ef62808Sisuckatcs   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
257*8ef62808Sisuckatcs }
258*8ef62808Sisuckatcs 
259*8ef62808Sisuckatcs void array_change_b(void) {
260*8ef62808Sisuckatcs   int arr[] = {1, 2};
261*8ef62808Sisuckatcs 
262*8ef62808Sisuckatcs   auto &[a, b] = arr;
263*8ef62808Sisuckatcs 
264*8ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
265*8ef62808Sisuckatcs   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
266*8ef62808Sisuckatcs 
267*8ef62808Sisuckatcs   a = 3;
268*8ef62808Sisuckatcs   clang_analyzer_eval(a == 3); // expected-warning{{TRUE}}
269*8ef62808Sisuckatcs 
270*8ef62808Sisuckatcs   clang_analyzer_eval(arr[0] == 3); // expected-warning{{TRUE}}
271*8ef62808Sisuckatcs   clang_analyzer_eval(arr[1] == 2); // expected-warning{{TRUE}}
272*8ef62808Sisuckatcs }
273*8ef62808Sisuckatcs 
274*8ef62808Sisuckatcs void array_small_a(void) {
275*8ef62808Sisuckatcs   int arr[5];
276*8ef62808Sisuckatcs 
277*8ef62808Sisuckatcs   auto [a, b, c, d, e] = arr;
278*8ef62808Sisuckatcs 
279*8ef62808Sisuckatcs   int x = e; // expected-warning{{Assigned value is garbage or undefined}}
280*8ef62808Sisuckatcs }
281*8ef62808Sisuckatcs 
282*8ef62808Sisuckatcs void array_big_a(void) {
283*8ef62808Sisuckatcs   int arr[6];
284*8ef62808Sisuckatcs 
285*8ef62808Sisuckatcs   auto [a, b, c, d, e, f] = arr;
286*8ef62808Sisuckatcs 
287*8ef62808Sisuckatcs   // FIXME: These will be Undefined when we handle reading Undefined values from lazyCompoundVal.
288*8ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{UNKNOWN}}
289*8ef62808Sisuckatcs   clang_analyzer_eval(b == 2); // expected-warning{{UNKNOWN}}
290*8ef62808Sisuckatcs   clang_analyzer_eval(c == 3); // expected-warning{{UNKNOWN}}
291*8ef62808Sisuckatcs   clang_analyzer_eval(d == 4); // expected-warning{{UNKNOWN}}
292*8ef62808Sisuckatcs   clang_analyzer_eval(e == 5); // expected-warning{{UNKNOWN}}
293*8ef62808Sisuckatcs   clang_analyzer_eval(f == 6); // expected-warning{{UNKNOWN}}
294*8ef62808Sisuckatcs }
295