xref: /llvm-project/clang/test/Analysis/uninit-structured-binding-struct.cpp (revision e77ac66b8c1cf4f09f931d37749ed258f122d708)
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