1*e77ac66bSisuckatcs // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
2*e77ac66bSisuckatcs
3*e77ac66bSisuckatcs void clang_analyzer_eval(bool);
4*e77ac66bSisuckatcs
5*e77ac66bSisuckatcs struct s {
6*e77ac66bSisuckatcs int a;
7*e77ac66bSisuckatcs int b;
8*e77ac66bSisuckatcs };
9*e77ac66bSisuckatcs
a(void)10*e77ac66bSisuckatcs void a(void) {
11*e77ac66bSisuckatcs s tst;
12*e77ac66bSisuckatcs
13*e77ac66bSisuckatcs auto [i, j] = tst;
14*e77ac66bSisuckatcs
15*e77ac66bSisuckatcs int x = i; // expected-warning{{Assigned value is garbage or undefined}}
16*e77ac66bSisuckatcs }
17*e77ac66bSisuckatcs
b(void)18*e77ac66bSisuckatcs void b(void) {
19*e77ac66bSisuckatcs s tst;
20*e77ac66bSisuckatcs tst.a = 1;
21*e77ac66bSisuckatcs
22*e77ac66bSisuckatcs auto [i, j] = tst;
23*e77ac66bSisuckatcs
24*e77ac66bSisuckatcs clang_analyzer_eval(i == 1); // expected-warning{{TRUE}}
25*e77ac66bSisuckatcs int y = j; // expected-warning{{Assigned value is garbage or undefined}}
26*e77ac66bSisuckatcs }
27*e77ac66bSisuckatcs
c(void)28*e77ac66bSisuckatcs void c(void) {
29*e77ac66bSisuckatcs s tst;
30*e77ac66bSisuckatcs
31*e77ac66bSisuckatcs auto &[i, j] = tst;
32*e77ac66bSisuckatcs
33*e77ac66bSisuckatcs int x = i; // expected-warning{{Assigned value is garbage or undefined}}
34*e77ac66bSisuckatcs }
35*e77ac66bSisuckatcs
d(void)36*e77ac66bSisuckatcs void d(void) {
37*e77ac66bSisuckatcs s tst;
38*e77ac66bSisuckatcs tst.a = 1;
39*e77ac66bSisuckatcs
40*e77ac66bSisuckatcs auto &[i, j] = tst;
41*e77ac66bSisuckatcs
42*e77ac66bSisuckatcs clang_analyzer_eval(i == 1); // expected-warning{{TRUE}}
43*e77ac66bSisuckatcs i = 2;
44*e77ac66bSisuckatcs clang_analyzer_eval(tst.a == 2); // expected-warning{{TRUE}}
45*e77ac66bSisuckatcs
46*e77ac66bSisuckatcs int y = j; // expected-warning{{Assigned value is garbage or undefined}}
47*e77ac66bSisuckatcs }
48*e77ac66bSisuckatcs
e(void)49*e77ac66bSisuckatcs void e(void) {
50*e77ac66bSisuckatcs s tst;
51*e77ac66bSisuckatcs tst.a = 1;
52*e77ac66bSisuckatcs
53*e77ac66bSisuckatcs auto &[i, j] = tst;
54*e77ac66bSisuckatcs
55*e77ac66bSisuckatcs clang_analyzer_eval(i == 1); // expected-warning{{TRUE}}
56*e77ac66bSisuckatcs
57*e77ac66bSisuckatcs tst.b = 2;
58*e77ac66bSisuckatcs clang_analyzer_eval(j == 2); // expected-warning{{TRUE}}
59*e77ac66bSisuckatcs }
60*e77ac66bSisuckatcs
f(void)61*e77ac66bSisuckatcs void f(void) {
62*e77ac66bSisuckatcs s tst;
63*e77ac66bSisuckatcs
64*e77ac66bSisuckatcs auto &&[i, j] = tst;
65*e77ac66bSisuckatcs
66*e77ac66bSisuckatcs int x = i; // expected-warning{{Assigned value is garbage or undefined}}
67*e77ac66bSisuckatcs }
68*e77ac66bSisuckatcs
g(void)69*e77ac66bSisuckatcs void g(void) {
70*e77ac66bSisuckatcs s tst;
71*e77ac66bSisuckatcs tst.a = 1;
72*e77ac66bSisuckatcs
73*e77ac66bSisuckatcs auto &&[i, j] = tst;
74*e77ac66bSisuckatcs
75*e77ac66bSisuckatcs clang_analyzer_eval(i == 1); // expected-warning{{TRUE}}
76*e77ac66bSisuckatcs int y = j; // expected-warning{{Assigned value is garbage or undefined}}
77*e77ac66bSisuckatcs }
78*e77ac66bSisuckatcs
79*e77ac66bSisuckatcs struct s2 {
80*e77ac66bSisuckatcs int a = 1;
81*e77ac66bSisuckatcs int b = 2;
82*e77ac66bSisuckatcs };
83*e77ac66bSisuckatcs
84*e77ac66bSisuckatcs struct s3 {
85*e77ac66bSisuckatcs s x;
86*e77ac66bSisuckatcs s2 y;
87*e77ac66bSisuckatcs };
88*e77ac66bSisuckatcs
h(void)89*e77ac66bSisuckatcs void h(void) {
90*e77ac66bSisuckatcs s3 tst;
91*e77ac66bSisuckatcs
92*e77ac66bSisuckatcs clang_analyzer_eval(tst.y.a == 1); // expected-warning{{TRUE}}
93*e77ac66bSisuckatcs
94*e77ac66bSisuckatcs auto [i, j] = tst;
95*e77ac66bSisuckatcs
96*e77ac66bSisuckatcs // FIXME: These should be undefined, but we have to fix
97*e77ac66bSisuckatcs // reading undefined from lazy compound values first.
98*e77ac66bSisuckatcs clang_analyzer_eval(i.a); // expected-warning{{UNKNOWN}}
99*e77ac66bSisuckatcs clang_analyzer_eval(i.b); // expected-warning{{UNKNOWN}}
100*e77ac66bSisuckatcs
101*e77ac66bSisuckatcs clang_analyzer_eval(j.a == 1); // expected-warning{{TRUE}}
102*e77ac66bSisuckatcs clang_analyzer_eval(j.b == 2); // expected-warning{{TRUE}}
103*e77ac66bSisuckatcs }
104*e77ac66bSisuckatcs
i(void)105*e77ac66bSisuckatcs void i(void) {
106*e77ac66bSisuckatcs s3 tst;
107*e77ac66bSisuckatcs
108*e77ac66bSisuckatcs clang_analyzer_eval(tst.y.a == 1); // expected-warning{{TRUE}}
109*e77ac66bSisuckatcs
110*e77ac66bSisuckatcs auto &[i, j] = tst;
111*e77ac66bSisuckatcs j.a = 3;
112*e77ac66bSisuckatcs
113*e77ac66bSisuckatcs clang_analyzer_eval(tst.y.a == 3); // expected-warning{{TRUE}}
114*e77ac66bSisuckatcs clang_analyzer_eval(tst.y.b == 2); // expected-warning{{TRUE}}
115*e77ac66bSisuckatcs clang_analyzer_eval(j.b == 2); // expected-warning{{TRUE}}
116*e77ac66bSisuckatcs }
117