1*a618d5e0Sisuckatcs // RUN: %clang_analyze_cc1 -Wno-ignored-reference-qualifiers -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
2*a618d5e0Sisuckatcs
3*a618d5e0Sisuckatcs #include "Inputs/system-header-simulator-cxx.h"
4*a618d5e0Sisuckatcs
5*a618d5e0Sisuckatcs void clang_analyzer_eval(bool);
6*a618d5e0Sisuckatcs
7*a618d5e0Sisuckatcs namespace std {
8*a618d5e0Sisuckatcs template <typename T>
9*a618d5e0Sisuckatcs struct tuple_size {
10*a618d5e0Sisuckatcs };
11*a618d5e0Sisuckatcs
12*a618d5e0Sisuckatcs template <std::size_t I, typename T>
13*a618d5e0Sisuckatcs struct tuple_element {
14*a618d5e0Sisuckatcs };
15*a618d5e0Sisuckatcs
16*a618d5e0Sisuckatcs // The std::pair in our system header simulator is not tuple-like, so a tuple-like mock is created here
17*a618d5e0Sisuckatcs template <typename T1, typename T2>
18*a618d5e0Sisuckatcs struct mock_pair {
19*a618d5e0Sisuckatcs T1 first;
20*a618d5e0Sisuckatcs T2 second;
21*a618d5e0Sisuckatcs };
22*a618d5e0Sisuckatcs template <typename T1, typename T2>
23*a618d5e0Sisuckatcs struct tuple_size<mock_pair<T1, T2>> {
24*a618d5e0Sisuckatcs static const std::size_t value = 2;
25*a618d5e0Sisuckatcs };
26*a618d5e0Sisuckatcs
27*a618d5e0Sisuckatcs template <typename T1, typename T2>
28*a618d5e0Sisuckatcs struct tuple_element<0, mock_pair<T1, T2>> {
29*a618d5e0Sisuckatcs using type = T1;
30*a618d5e0Sisuckatcs };
31*a618d5e0Sisuckatcs
32*a618d5e0Sisuckatcs template <typename T1, typename T2>
33*a618d5e0Sisuckatcs struct tuple_element<1, mock_pair<T1, T2>> {
34*a618d5e0Sisuckatcs using type = T2;
35*a618d5e0Sisuckatcs };
36*a618d5e0Sisuckatcs
37*a618d5e0Sisuckatcs template <std::size_t I, class T>
38*a618d5e0Sisuckatcs using tuple_element_t = typename tuple_element<I, T>::type;
39*a618d5e0Sisuckatcs
40*a618d5e0Sisuckatcs template <std::size_t I, class T1, class T2>
41*a618d5e0Sisuckatcs constexpr std::tuple_element_t<I, std::mock_pair<T1, T2>> &
get(std::mock_pair<T1,T2> & p)42*a618d5e0Sisuckatcs get(std::mock_pair<T1, T2> &p) noexcept {
43*a618d5e0Sisuckatcs if (I == 0)
44*a618d5e0Sisuckatcs return p.first;
45*a618d5e0Sisuckatcs else
46*a618d5e0Sisuckatcs return p.second;
47*a618d5e0Sisuckatcs }
48*a618d5e0Sisuckatcs
49*a618d5e0Sisuckatcs template <std::size_t I, class T1, class T2>
50*a618d5e0Sisuckatcs constexpr const std::tuple_element_t<I, std::mock_pair<T1, T2>> &
get(const std::mock_pair<T1,T2> & p)51*a618d5e0Sisuckatcs get(const std::mock_pair<T1, T2> &p) noexcept {
52*a618d5e0Sisuckatcs if (I == 0)
53*a618d5e0Sisuckatcs return p.first;
54*a618d5e0Sisuckatcs else
55*a618d5e0Sisuckatcs return p.second;
56*a618d5e0Sisuckatcs }
57*a618d5e0Sisuckatcs
58*a618d5e0Sisuckatcs template <std::size_t I, class T1, class T2>
59*a618d5e0Sisuckatcs constexpr std::tuple_element_t<I, std::mock_pair<T1, T2>> &&
get(std::mock_pair<T1,T2> && p)60*a618d5e0Sisuckatcs get(std::mock_pair<T1, T2> &&p) noexcept {
61*a618d5e0Sisuckatcs
62*a618d5e0Sisuckatcs if (I == 0)
63*a618d5e0Sisuckatcs return static_cast<std::tuple_element_t<I, std::mock_pair<T1, T2>> &&>(p.first);
64*a618d5e0Sisuckatcs else
65*a618d5e0Sisuckatcs return static_cast<std::tuple_element_t<I, std::mock_pair<T1, T2>> &&>(p.second);
66*a618d5e0Sisuckatcs }
67*a618d5e0Sisuckatcs
68*a618d5e0Sisuckatcs template <std::size_t I, class T1, class T2>
69*a618d5e0Sisuckatcs constexpr const std::tuple_element_t<I, std::mock_pair<T1, T2>> &&
get(const std::mock_pair<T1,T2> && p)70*a618d5e0Sisuckatcs get(const std::mock_pair<T1, T2> &&p) noexcept {
71*a618d5e0Sisuckatcs if (I == 0)
72*a618d5e0Sisuckatcs return static_cast<std::tuple_element_t<I, std::mock_pair<T1, T2>> &&>(p.first);
73*a618d5e0Sisuckatcs else
74*a618d5e0Sisuckatcs return static_cast<std::tuple_element_t<I, std::mock_pair<T1, T2>> &&>(p.second);
75*a618d5e0Sisuckatcs }
76*a618d5e0Sisuckatcs
77*a618d5e0Sisuckatcs } // namespace std
78*a618d5e0Sisuckatcs // A utility that generates a tuple-like struct with 2 fields
79*a618d5e0Sisuckatcs // of the same type. The fields are 'first' and 'second'
80*a618d5e0Sisuckatcs #define GENERATE_TUPLE_LIKE_STRUCT(name, element_type) \
81*a618d5e0Sisuckatcs struct name { \
82*a618d5e0Sisuckatcs element_type first; \
83*a618d5e0Sisuckatcs element_type second; \
84*a618d5e0Sisuckatcs }; \
85*a618d5e0Sisuckatcs \
86*a618d5e0Sisuckatcs namespace std { \
87*a618d5e0Sisuckatcs template <> \
88*a618d5e0Sisuckatcs struct tuple_size<name> { \
89*a618d5e0Sisuckatcs static const std::size_t value = 2; \
90*a618d5e0Sisuckatcs }; \
91*a618d5e0Sisuckatcs \
92*a618d5e0Sisuckatcs template <std::size_t I> \
93*a618d5e0Sisuckatcs struct tuple_element<I, name> { \
94*a618d5e0Sisuckatcs using type = element_type; \
95*a618d5e0Sisuckatcs }; \
96*a618d5e0Sisuckatcs }
97*a618d5e0Sisuckatcs
non_user_defined_by_value(void)98*a618d5e0Sisuckatcs void non_user_defined_by_value(void) {
99*a618d5e0Sisuckatcs std::mock_pair<int, int> p = {1, 2};
100*a618d5e0Sisuckatcs
101*a618d5e0Sisuckatcs auto [u, v] = p;
102*a618d5e0Sisuckatcs
103*a618d5e0Sisuckatcs clang_analyzer_eval(u == 1); // expected-warning{{TRUE}}
104*a618d5e0Sisuckatcs clang_analyzer_eval(v == 2); // expected-warning{{TRUE}}
105*a618d5e0Sisuckatcs
106*a618d5e0Sisuckatcs int x = u;
107*a618d5e0Sisuckatcs u = 10;
108*a618d5e0Sisuckatcs int y = u;
109*a618d5e0Sisuckatcs
110*a618d5e0Sisuckatcs clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
111*a618d5e0Sisuckatcs clang_analyzer_eval(u == 10); // expected-warning{{TRUE}}
112*a618d5e0Sisuckatcs
113*a618d5e0Sisuckatcs clang_analyzer_eval(y == 10); // expected-warning{{TRUE}}
114*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 1); // expected-warning{{TRUE}}
115*a618d5e0Sisuckatcs
116*a618d5e0Sisuckatcs p.first = 5;
117*a618d5e0Sisuckatcs
118*a618d5e0Sisuckatcs clang_analyzer_eval(u == 10); // expected-warning{{TRUE}}
119*a618d5e0Sisuckatcs }
120*a618d5e0Sisuckatcs
non_user_defined_by_lref(void)121*a618d5e0Sisuckatcs void non_user_defined_by_lref(void) {
122*a618d5e0Sisuckatcs std::mock_pair<int, int> p = {1, 2};
123*a618d5e0Sisuckatcs
124*a618d5e0Sisuckatcs auto &[u, v] = p;
125*a618d5e0Sisuckatcs
126*a618d5e0Sisuckatcs int x = u;
127*a618d5e0Sisuckatcs u = 10;
128*a618d5e0Sisuckatcs int y = u;
129*a618d5e0Sisuckatcs
130*a618d5e0Sisuckatcs clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
131*a618d5e0Sisuckatcs clang_analyzer_eval(u == 10); // expected-warning{{TRUE}}
132*a618d5e0Sisuckatcs
133*a618d5e0Sisuckatcs clang_analyzer_eval(y == 10); // expected-warning{{TRUE}}
134*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 10); // expected-warning{{TRUE}}
135*a618d5e0Sisuckatcs
136*a618d5e0Sisuckatcs clang_analyzer_eval(v == 2); // expected-warning{{TRUE}}
137*a618d5e0Sisuckatcs clang_analyzer_eval(p.second == 2); // expected-warning{{TRUE}}
138*a618d5e0Sisuckatcs
139*a618d5e0Sisuckatcs p.first = 5;
140*a618d5e0Sisuckatcs
141*a618d5e0Sisuckatcs clang_analyzer_eval(u == 5); // expected-warning{{TRUE}}
142*a618d5e0Sisuckatcs }
143*a618d5e0Sisuckatcs
non_user_defined_by_rref(void)144*a618d5e0Sisuckatcs void non_user_defined_by_rref(void) {
145*a618d5e0Sisuckatcs std::mock_pair<int, int> p = {1, 2};
146*a618d5e0Sisuckatcs
147*a618d5e0Sisuckatcs auto &&[u, v] = p;
148*a618d5e0Sisuckatcs
149*a618d5e0Sisuckatcs int x = u;
150*a618d5e0Sisuckatcs u = 10;
151*a618d5e0Sisuckatcs int y = u;
152*a618d5e0Sisuckatcs
153*a618d5e0Sisuckatcs clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
154*a618d5e0Sisuckatcs clang_analyzer_eval(u == 10); // expected-warning{{TRUE}}
155*a618d5e0Sisuckatcs
156*a618d5e0Sisuckatcs clang_analyzer_eval(y == 10); // expected-warning{{TRUE}}
157*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 10); // expected-warning{{TRUE}}
158*a618d5e0Sisuckatcs
159*a618d5e0Sisuckatcs clang_analyzer_eval(v == 2); // expected-warning{{TRUE}}
160*a618d5e0Sisuckatcs clang_analyzer_eval(p.second == 2); // expected-warning{{TRUE}}
161*a618d5e0Sisuckatcs
162*a618d5e0Sisuckatcs p.first = 5;
163*a618d5e0Sisuckatcs
164*a618d5e0Sisuckatcs clang_analyzer_eval(u == 5); // expected-warning{{TRUE}}
165*a618d5e0Sisuckatcs }
166*a618d5e0Sisuckatcs
167*a618d5e0Sisuckatcs GENERATE_TUPLE_LIKE_STRUCT(Test, int);
168*a618d5e0Sisuckatcs
169*a618d5e0Sisuckatcs template <std::size_t I>
get(Test t)170*a618d5e0Sisuckatcs int get(Test t) {
171*a618d5e0Sisuckatcs if (I == 0) {
172*a618d5e0Sisuckatcs t.second = 10;
173*a618d5e0Sisuckatcs return t.first;
174*a618d5e0Sisuckatcs } else {
175*a618d5e0Sisuckatcs t.first = 20;
176*a618d5e0Sisuckatcs return t.second;
177*a618d5e0Sisuckatcs }
178*a618d5e0Sisuckatcs }
179*a618d5e0Sisuckatcs
user_defined_get_val_by_val(void)180*a618d5e0Sisuckatcs void user_defined_get_val_by_val(void) {
181*a618d5e0Sisuckatcs Test p{1, 2};
182*a618d5e0Sisuckatcs auto [u, v] = p;
183*a618d5e0Sisuckatcs
184*a618d5e0Sisuckatcs clang_analyzer_eval(u == 1); // expected-warning{{TRUE}}
185*a618d5e0Sisuckatcs
186*a618d5e0Sisuckatcs u = 8;
187*a618d5e0Sisuckatcs
188*a618d5e0Sisuckatcs int x = u;
189*a618d5e0Sisuckatcs
190*a618d5e0Sisuckatcs clang_analyzer_eval(x == 8); // expected-warning{{TRUE}}
191*a618d5e0Sisuckatcs
192*a618d5e0Sisuckatcs clang_analyzer_eval(u == 8); // expected-warning{{TRUE}}
193*a618d5e0Sisuckatcs clang_analyzer_eval(v == 2); // expected-warning{{TRUE}}
194*a618d5e0Sisuckatcs
195*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 1); // expected-warning{{TRUE}}
196*a618d5e0Sisuckatcs clang_analyzer_eval(p.second == 2); // expected-warning{{TRUE}}
197*a618d5e0Sisuckatcs
198*a618d5e0Sisuckatcs p.first = 5;
199*a618d5e0Sisuckatcs
200*a618d5e0Sisuckatcs clang_analyzer_eval(u == 8); // expected-warning{{TRUE}}
201*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 5); // expected-warning{{TRUE}}
202*a618d5e0Sisuckatcs }
203*a618d5e0Sisuckatcs
204*a618d5e0Sisuckatcs GENERATE_TUPLE_LIKE_STRUCT(Test2, int);
205*a618d5e0Sisuckatcs
206*a618d5e0Sisuckatcs template <std::size_t I>
get(Test2 & t)207*a618d5e0Sisuckatcs int get(Test2 &t) {
208*a618d5e0Sisuckatcs if (I == 0) {
209*a618d5e0Sisuckatcs t.second = 10;
210*a618d5e0Sisuckatcs return t.first;
211*a618d5e0Sisuckatcs } else {
212*a618d5e0Sisuckatcs t.first = 20;
213*a618d5e0Sisuckatcs return t.second;
214*a618d5e0Sisuckatcs }
215*a618d5e0Sisuckatcs }
216*a618d5e0Sisuckatcs
user_defined_get_val_by_lref(void)217*a618d5e0Sisuckatcs void user_defined_get_val_by_lref(void) {
218*a618d5e0Sisuckatcs Test2 p{1, 2};
219*a618d5e0Sisuckatcs
220*a618d5e0Sisuckatcs auto &[u, v] = p;
221*a618d5e0Sisuckatcs
222*a618d5e0Sisuckatcs clang_analyzer_eval(u == 1); // expected-warning{{TRUE}}
223*a618d5e0Sisuckatcs clang_analyzer_eval(v == 10); // expected-warning{{TRUE}}
224*a618d5e0Sisuckatcs
225*a618d5e0Sisuckatcs u = 8;
226*a618d5e0Sisuckatcs
227*a618d5e0Sisuckatcs int x = u;
228*a618d5e0Sisuckatcs
229*a618d5e0Sisuckatcs clang_analyzer_eval(x == 8); // expected-warning{{TRUE}}
230*a618d5e0Sisuckatcs
231*a618d5e0Sisuckatcs clang_analyzer_eval(u == 8); // expected-warning{{TRUE}}
232*a618d5e0Sisuckatcs clang_analyzer_eval(v == 10); // expected-warning{{TRUE}}
233*a618d5e0Sisuckatcs
234*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 20); // expected-warning{{TRUE}}
235*a618d5e0Sisuckatcs clang_analyzer_eval(p.second == 10); // expected-warning{{TRUE}}
236*a618d5e0Sisuckatcs
237*a618d5e0Sisuckatcs p.first = 5;
238*a618d5e0Sisuckatcs
239*a618d5e0Sisuckatcs clang_analyzer_eval(u == 8); // expected-warning{{TRUE}}
240*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 5); // expected-warning{{TRUE}}
241*a618d5e0Sisuckatcs }
242*a618d5e0Sisuckatcs
user_defined_get_val_by_rref(void)243*a618d5e0Sisuckatcs void user_defined_get_val_by_rref(void) {
244*a618d5e0Sisuckatcs Test2 p{1, 2};
245*a618d5e0Sisuckatcs
246*a618d5e0Sisuckatcs auto &&[u, v] = p;
247*a618d5e0Sisuckatcs
248*a618d5e0Sisuckatcs clang_analyzer_eval(u == 1); // expected-warning{{TRUE}}
249*a618d5e0Sisuckatcs clang_analyzer_eval(v == 10); // expected-warning{{TRUE}}
250*a618d5e0Sisuckatcs
251*a618d5e0Sisuckatcs u = 8;
252*a618d5e0Sisuckatcs
253*a618d5e0Sisuckatcs int x = u;
254*a618d5e0Sisuckatcs
255*a618d5e0Sisuckatcs clang_analyzer_eval(x == 8); // expected-warning{{TRUE}}
256*a618d5e0Sisuckatcs
257*a618d5e0Sisuckatcs clang_analyzer_eval(u == 8); // expected-warning{{TRUE}}
258*a618d5e0Sisuckatcs clang_analyzer_eval(v == 10); // expected-warning{{TRUE}}
259*a618d5e0Sisuckatcs
260*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 20); // expected-warning{{TRUE}}
261*a618d5e0Sisuckatcs clang_analyzer_eval(p.second == 10); // expected-warning{{TRUE}}
262*a618d5e0Sisuckatcs
263*a618d5e0Sisuckatcs p.first = 5;
264*a618d5e0Sisuckatcs
265*a618d5e0Sisuckatcs clang_analyzer_eval(u == 8); // expected-warning{{TRUE}}
266*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 5); // expected-warning{{TRUE}}
267*a618d5e0Sisuckatcs }
268*a618d5e0Sisuckatcs
269*a618d5e0Sisuckatcs struct MixedTest {
270*a618d5e0Sisuckatcs int x;
271*a618d5e0Sisuckatcs char &&y;
272*a618d5e0Sisuckatcs int &z;
273*a618d5e0Sisuckatcs };
274*a618d5e0Sisuckatcs
275*a618d5e0Sisuckatcs namespace std {
276*a618d5e0Sisuckatcs template <>
277*a618d5e0Sisuckatcs struct tuple_size<MixedTest> {
278*a618d5e0Sisuckatcs static const std::size_t value = 3;
279*a618d5e0Sisuckatcs };
280*a618d5e0Sisuckatcs
281*a618d5e0Sisuckatcs template <>
282*a618d5e0Sisuckatcs struct tuple_element<0, MixedTest> {
283*a618d5e0Sisuckatcs using type = int;
284*a618d5e0Sisuckatcs };
285*a618d5e0Sisuckatcs
286*a618d5e0Sisuckatcs template <>
287*a618d5e0Sisuckatcs struct tuple_element<1, MixedTest> {
288*a618d5e0Sisuckatcs using type = char &&;
289*a618d5e0Sisuckatcs };
290*a618d5e0Sisuckatcs
291*a618d5e0Sisuckatcs template <>
292*a618d5e0Sisuckatcs struct tuple_element<2, MixedTest> {
293*a618d5e0Sisuckatcs using type = int &;
294*a618d5e0Sisuckatcs };
295*a618d5e0Sisuckatcs
296*a618d5e0Sisuckatcs template <std::size_t I, typename T>
297*a618d5e0Sisuckatcs using tuple_element_t = typename tuple_element<I, T>::type;
298*a618d5e0Sisuckatcs
299*a618d5e0Sisuckatcs } // namespace std
300*a618d5e0Sisuckatcs
301*a618d5e0Sisuckatcs template <std::size_t I>
get(const MixedTest & t)302*a618d5e0Sisuckatcs const std::tuple_element_t<I, MixedTest> &get(const MixedTest &t) {}
303*a618d5e0Sisuckatcs
304*a618d5e0Sisuckatcs template <>
get(const MixedTest & t)305*a618d5e0Sisuckatcs const std::tuple_element_t<0, MixedTest> &get<0>(const MixedTest &t) {
306*a618d5e0Sisuckatcs return t.x;
307*a618d5e0Sisuckatcs }
308*a618d5e0Sisuckatcs
309*a618d5e0Sisuckatcs template <>
get(const MixedTest & t)310*a618d5e0Sisuckatcs const std::tuple_element_t<1, MixedTest> &get<1>(const MixedTest &t) {
311*a618d5e0Sisuckatcs return t.y;
312*a618d5e0Sisuckatcs }
313*a618d5e0Sisuckatcs
314*a618d5e0Sisuckatcs template <>
get(const MixedTest & t)315*a618d5e0Sisuckatcs const std::tuple_element_t<2, MixedTest> &get<2>(const MixedTest &t) {
316*a618d5e0Sisuckatcs return t.z;
317*a618d5e0Sisuckatcs }
318*a618d5e0Sisuckatcs
mixed_type_cref(void)319*a618d5e0Sisuckatcs void mixed_type_cref(void) {
320*a618d5e0Sisuckatcs int x = 1;
321*a618d5e0Sisuckatcs char y = 2;
322*a618d5e0Sisuckatcs int z = 3;
323*a618d5e0Sisuckatcs
324*a618d5e0Sisuckatcs MixedTest m{x, std::move(y), z};
325*a618d5e0Sisuckatcs const auto &[a, b, c] = m;
326*a618d5e0Sisuckatcs
327*a618d5e0Sisuckatcs clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
328*a618d5e0Sisuckatcs clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
329*a618d5e0Sisuckatcs clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
330*a618d5e0Sisuckatcs
331*a618d5e0Sisuckatcs clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
332*a618d5e0Sisuckatcs clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
333*a618d5e0Sisuckatcs clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
334*a618d5e0Sisuckatcs }
335*a618d5e0Sisuckatcs
336*a618d5e0Sisuckatcs template <std::size_t I>
get(MixedTest & t)337*a618d5e0Sisuckatcs std::tuple_element_t<I, MixedTest> &get(MixedTest &t) {}
338*a618d5e0Sisuckatcs
339*a618d5e0Sisuckatcs template <>
get(MixedTest & t)340*a618d5e0Sisuckatcs std::tuple_element_t<0, MixedTest> &get<0>(MixedTest &t) {
341*a618d5e0Sisuckatcs return t.x;
342*a618d5e0Sisuckatcs }
343*a618d5e0Sisuckatcs
344*a618d5e0Sisuckatcs template <>
get(MixedTest & t)345*a618d5e0Sisuckatcs std::tuple_element_t<1, MixedTest> &get<1>(MixedTest &t) {
346*a618d5e0Sisuckatcs return t.y;
347*a618d5e0Sisuckatcs }
348*a618d5e0Sisuckatcs
349*a618d5e0Sisuckatcs template <>
get(MixedTest & t)350*a618d5e0Sisuckatcs std::tuple_element_t<2, MixedTest> &get<2>(MixedTest &t) {
351*a618d5e0Sisuckatcs return t.z;
352*a618d5e0Sisuckatcs }
353*a618d5e0Sisuckatcs
mixed_type_lref(void)354*a618d5e0Sisuckatcs void mixed_type_lref(void) {
355*a618d5e0Sisuckatcs int x = 1;
356*a618d5e0Sisuckatcs char y = 2;
357*a618d5e0Sisuckatcs int z = 3;
358*a618d5e0Sisuckatcs
359*a618d5e0Sisuckatcs MixedTest m{x, std::move(y), z};
360*a618d5e0Sisuckatcs auto &[a, b, c] = m;
361*a618d5e0Sisuckatcs
362*a618d5e0Sisuckatcs a = 4;
363*a618d5e0Sisuckatcs b = 5;
364*a618d5e0Sisuckatcs c = 6;
365*a618d5e0Sisuckatcs
366*a618d5e0Sisuckatcs clang_analyzer_eval(get<0>(m) == 4); // expected-warning{{TRUE}}
367*a618d5e0Sisuckatcs clang_analyzer_eval(get<1>(m) == 5); // expected-warning{{TRUE}}
368*a618d5e0Sisuckatcs clang_analyzer_eval(get<2>(m) == 6); // expected-warning{{TRUE}}
369*a618d5e0Sisuckatcs
370*a618d5e0Sisuckatcs clang_analyzer_eval(get<0>(m) == 4); // expected-warning{{TRUE}}
371*a618d5e0Sisuckatcs clang_analyzer_eval(get<1>(m) == 5); // expected-warning{{TRUE}}
372*a618d5e0Sisuckatcs clang_analyzer_eval(get<2>(m) == 6); // expected-warning{{TRUE}}
373*a618d5e0Sisuckatcs
374*a618d5e0Sisuckatcs clang_analyzer_eval(z == 6); // expected-warning{{TRUE}}
375*a618d5e0Sisuckatcs }
376*a618d5e0Sisuckatcs
mixed_type_rref(void)377*a618d5e0Sisuckatcs void mixed_type_rref(void) {
378*a618d5e0Sisuckatcs int x = 1;
379*a618d5e0Sisuckatcs char y = 2;
380*a618d5e0Sisuckatcs int z = 3;
381*a618d5e0Sisuckatcs
382*a618d5e0Sisuckatcs MixedTest m{x, std::move(y), z};
383*a618d5e0Sisuckatcs auto &&[a, b, c] = m;
384*a618d5e0Sisuckatcs
385*a618d5e0Sisuckatcs a = 4;
386*a618d5e0Sisuckatcs b = 5;
387*a618d5e0Sisuckatcs c = 6;
388*a618d5e0Sisuckatcs
389*a618d5e0Sisuckatcs clang_analyzer_eval(get<0>(m) == 4); // expected-warning{{TRUE}}
390*a618d5e0Sisuckatcs clang_analyzer_eval(get<1>(m) == 5); // expected-warning{{TRUE}}
391*a618d5e0Sisuckatcs clang_analyzer_eval(get<2>(m) == 6); // expected-warning{{TRUE}}
392*a618d5e0Sisuckatcs
393*a618d5e0Sisuckatcs clang_analyzer_eval(get<0>(m) == 4); // expected-warning{{TRUE}}
394*a618d5e0Sisuckatcs clang_analyzer_eval(get<1>(m) == 5); // expected-warning{{TRUE}}
395*a618d5e0Sisuckatcs clang_analyzer_eval(get<2>(m) == 6); // expected-warning{{TRUE}}
396*a618d5e0Sisuckatcs
397*a618d5e0Sisuckatcs clang_analyzer_eval(z == 6); // expected-warning{{TRUE}}
398*a618d5e0Sisuckatcs }
399*a618d5e0Sisuckatcs
ref_val(void)400*a618d5e0Sisuckatcs void ref_val(void) {
401*a618d5e0Sisuckatcs int i = 1, j = 2;
402*a618d5e0Sisuckatcs std::mock_pair<int &, int &> p{i, j};
403*a618d5e0Sisuckatcs
404*a618d5e0Sisuckatcs auto [a, b] = p;
405*a618d5e0Sisuckatcs clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
406*a618d5e0Sisuckatcs clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
407*a618d5e0Sisuckatcs
408*a618d5e0Sisuckatcs a = 3;
409*a618d5e0Sisuckatcs b = 4;
410*a618d5e0Sisuckatcs
411*a618d5e0Sisuckatcs clang_analyzer_eval(p.first == 3); // expected-warning{{TRUE}}
412*a618d5e0Sisuckatcs clang_analyzer_eval(p.second == 4); // expected-warning{{TRUE}}
413*a618d5e0Sisuckatcs
414*a618d5e0Sisuckatcs clang_analyzer_eval(a == 3); // expected-warning{{TRUE}}
415*a618d5e0Sisuckatcs clang_analyzer_eval(b == 4); // expected-warning{{TRUE}}
416*a618d5e0Sisuckatcs }
417*a618d5e0Sisuckatcs
418*a618d5e0Sisuckatcs struct Small_Non_POD {
419*a618d5e0Sisuckatcs int i;
420*a618d5e0Sisuckatcs int j;
421*a618d5e0Sisuckatcs };
422*a618d5e0Sisuckatcs
non_user_defined_small_non_pod_by_value(void)423*a618d5e0Sisuckatcs void non_user_defined_small_non_pod_by_value(void) {
424*a618d5e0Sisuckatcs std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {1, 2}};
425*a618d5e0Sisuckatcs
426*a618d5e0Sisuckatcs auto [a, b] = p;
427*a618d5e0Sisuckatcs
428*a618d5e0Sisuckatcs clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}
429*a618d5e0Sisuckatcs clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}
430*a618d5e0Sisuckatcs
431*a618d5e0Sisuckatcs clang_analyzer_eval(b.i == 1); // expected-warning{{TRUE}}
432*a618d5e0Sisuckatcs clang_analyzer_eval(b.j == 2); // expected-warning{{TRUE}}
433*a618d5e0Sisuckatcs
434*a618d5e0Sisuckatcs a.i = 3;
435*a618d5e0Sisuckatcs a.j = 4;
436*a618d5e0Sisuckatcs
437*a618d5e0Sisuckatcs b.i = 5;
438*a618d5e0Sisuckatcs b.j = 6;
439*a618d5e0Sisuckatcs
440*a618d5e0Sisuckatcs clang_analyzer_eval(a.i == 3); // expected-warning{{TRUE}}
441*a618d5e0Sisuckatcs clang_analyzer_eval(a.j == 4); // expected-warning{{TRUE}}
442*a618d5e0Sisuckatcs
443*a618d5e0Sisuckatcs clang_analyzer_eval(b.i == 5); // expected-warning{{TRUE}}
444*a618d5e0Sisuckatcs clang_analyzer_eval(b.j == 6); // expected-warning{{TRUE}}
445*a618d5e0Sisuckatcs
446*a618d5e0Sisuckatcs clang_analyzer_eval(p.first.i == 1); // expected-warning{{TRUE}}
447*a618d5e0Sisuckatcs clang_analyzer_eval(p.first.j == 2); // expected-warning{{TRUE}}
448*a618d5e0Sisuckatcs
449*a618d5e0Sisuckatcs clang_analyzer_eval(p.second.i == 1); // expected-warning{{TRUE}}
450*a618d5e0Sisuckatcs clang_analyzer_eval(p.second.j == 2); // expected-warning{{TRUE}}
451*a618d5e0Sisuckatcs }
452*a618d5e0Sisuckatcs
non_user_defined_small_non_pod_by_lref(void)453*a618d5e0Sisuckatcs void non_user_defined_small_non_pod_by_lref(void) {
454*a618d5e0Sisuckatcs std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {1, 2}};
455*a618d5e0Sisuckatcs
456*a618d5e0Sisuckatcs auto &[a, b] = p;
457*a618d5e0Sisuckatcs
458*a618d5e0Sisuckatcs clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}
459*a618d5e0Sisuckatcs clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}
460*a618d5e0Sisuckatcs
461*a618d5e0Sisuckatcs clang_analyzer_eval(b.i == 1); // expected-warning{{TRUE}}
462*a618d5e0Sisuckatcs clang_analyzer_eval(b.j == 2); // expected-warning{{TRUE}}
463*a618d5e0Sisuckatcs
464*a618d5e0Sisuckatcs a.i = 3;
465*a618d5e0Sisuckatcs a.j = 4;
466*a618d5e0Sisuckatcs
467*a618d5e0Sisuckatcs b.i = 5;
468*a618d5e0Sisuckatcs b.j = 6;
469*a618d5e0Sisuckatcs
470*a618d5e0Sisuckatcs clang_analyzer_eval(a.i == 3); // expected-warning{{TRUE}}
471*a618d5e0Sisuckatcs clang_analyzer_eval(a.j == 4); // expected-warning{{TRUE}}
472*a618d5e0Sisuckatcs
473*a618d5e0Sisuckatcs clang_analyzer_eval(b.i == 5); // expected-warning{{TRUE}}
474*a618d5e0Sisuckatcs clang_analyzer_eval(b.j == 6); // expected-warning{{TRUE}}
475*a618d5e0Sisuckatcs
476*a618d5e0Sisuckatcs clang_analyzer_eval(p.first.i == 3); // expected-warning{{TRUE}}
477*a618d5e0Sisuckatcs clang_analyzer_eval(p.first.j == 4); // expected-warning{{TRUE}}
478*a618d5e0Sisuckatcs
479*a618d5e0Sisuckatcs clang_analyzer_eval(p.second.i == 5); // expected-warning{{TRUE}}
480*a618d5e0Sisuckatcs clang_analyzer_eval(p.second.j == 6); // expected-warning{{TRUE}}
481*a618d5e0Sisuckatcs }
482*a618d5e0Sisuckatcs
non_user_defined_small_non_pod_by_rref(void)483*a618d5e0Sisuckatcs void non_user_defined_small_non_pod_by_rref(void) {
484*a618d5e0Sisuckatcs std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {1, 2}};
485*a618d5e0Sisuckatcs
486*a618d5e0Sisuckatcs auto &&[a, b] = p;
487*a618d5e0Sisuckatcs
488*a618d5e0Sisuckatcs clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}
489*a618d5e0Sisuckatcs clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}
490*a618d5e0Sisuckatcs
491*a618d5e0Sisuckatcs clang_analyzer_eval(b.i == 1); // expected-warning{{TRUE}}
492*a618d5e0Sisuckatcs clang_analyzer_eval(b.j == 2); // expected-warning{{TRUE}}
493*a618d5e0Sisuckatcs
494*a618d5e0Sisuckatcs a.i = 3;
495*a618d5e0Sisuckatcs a.j = 4;
496*a618d5e0Sisuckatcs
497*a618d5e0Sisuckatcs b.i = 5;
498*a618d5e0Sisuckatcs b.j = 6;
499*a618d5e0Sisuckatcs
500*a618d5e0Sisuckatcs clang_analyzer_eval(a.i == 3); // expected-warning{{TRUE}}
501*a618d5e0Sisuckatcs clang_analyzer_eval(a.j == 4); // expected-warning{{TRUE}}
502*a618d5e0Sisuckatcs
503*a618d5e0Sisuckatcs clang_analyzer_eval(b.i == 5); // expected-warning{{TRUE}}
504*a618d5e0Sisuckatcs clang_analyzer_eval(b.j == 6); // expected-warning{{TRUE}}
505*a618d5e0Sisuckatcs
506*a618d5e0Sisuckatcs clang_analyzer_eval(p.first.i == 3); // expected-warning{{TRUE}}
507*a618d5e0Sisuckatcs clang_analyzer_eval(p.first.j == 4); // expected-warning{{TRUE}}
508*a618d5e0Sisuckatcs
509*a618d5e0Sisuckatcs clang_analyzer_eval(p.second.i == 5); // expected-warning{{TRUE}}
510*a618d5e0Sisuckatcs clang_analyzer_eval(p.second.j == 6); // expected-warning{{TRUE}}
511*a618d5e0Sisuckatcs }
512*a618d5e0Sisuckatcs
513*a618d5e0Sisuckatcs GENERATE_TUPLE_LIKE_STRUCT(Uninit, int);
514*a618d5e0Sisuckatcs template <std::size_t I>
get(Uninit && t)515*a618d5e0Sisuckatcs int &get(Uninit &&t) {
516*a618d5e0Sisuckatcs if (I == 0) {
517*a618d5e0Sisuckatcs return t.first;
518*a618d5e0Sisuckatcs } else {
519*a618d5e0Sisuckatcs return t.second;
520*a618d5e0Sisuckatcs }
521*a618d5e0Sisuckatcs }
522*a618d5e0Sisuckatcs
uninit_a(void)523*a618d5e0Sisuckatcs void uninit_a(void) {
524*a618d5e0Sisuckatcs Uninit u;
525*a618d5e0Sisuckatcs
526*a618d5e0Sisuckatcs auto [a, b] = u;
527*a618d5e0Sisuckatcs
528*a618d5e0Sisuckatcs int x = a; // expected-warning{{Assigned value is garbage or undefined}}
529*a618d5e0Sisuckatcs }
530*a618d5e0Sisuckatcs
uninit_b(void)531*a618d5e0Sisuckatcs void uninit_b(void) {
532*a618d5e0Sisuckatcs Uninit u;
533*a618d5e0Sisuckatcs
534*a618d5e0Sisuckatcs auto [a, b] = u;
535*a618d5e0Sisuckatcs
536*a618d5e0Sisuckatcs int x = b; // expected-warning{{Assigned value is garbage or undefined}}
537*a618d5e0Sisuckatcs }
538*a618d5e0Sisuckatcs
539*a618d5e0Sisuckatcs GENERATE_TUPLE_LIKE_STRUCT(UninitCall, int);
540*a618d5e0Sisuckatcs template <std::size_t I>
get(UninitCall t)541*a618d5e0Sisuckatcs int get(UninitCall t) {
542*a618d5e0Sisuckatcs if (I == 0) {
543*a618d5e0Sisuckatcs return t.first;
544*a618d5e0Sisuckatcs } else {
545*a618d5e0Sisuckatcs return t.second;
546*a618d5e0Sisuckatcs }
547*a618d5e0Sisuckatcs }
548*a618d5e0Sisuckatcs
uninit_call(void)549*a618d5e0Sisuckatcs void uninit_call(void) {
550*a618d5e0Sisuckatcs UninitCall u;
551*a618d5e0Sisuckatcs
552*a618d5e0Sisuckatcs auto [a, b] = u;
553*a618d5e0Sisuckatcs
554*a618d5e0Sisuckatcs int x = a;
555*a618d5e0Sisuckatcs // expected-warning@543{{Undefined or garbage value returned to caller}}
556*a618d5e0Sisuckatcs }
557*a618d5e0Sisuckatcs
syntax_2()558*a618d5e0Sisuckatcs void syntax_2() {
559*a618d5e0Sisuckatcs std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {3, 4}};
560*a618d5e0Sisuckatcs
561*a618d5e0Sisuckatcs auto [a, b]{p};
562*a618d5e0Sisuckatcs
563*a618d5e0Sisuckatcs clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}
564*a618d5e0Sisuckatcs clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}
565*a618d5e0Sisuckatcs
566*a618d5e0Sisuckatcs clang_analyzer_eval(b.i == 3); // expected-warning{{TRUE}}
567*a618d5e0Sisuckatcs clang_analyzer_eval(b.j == 4); // expected-warning{{TRUE}}
568*a618d5e0Sisuckatcs }
569*a618d5e0Sisuckatcs
syntax_3()570*a618d5e0Sisuckatcs void syntax_3() {
571*a618d5e0Sisuckatcs std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {3, 4}};
572*a618d5e0Sisuckatcs
573*a618d5e0Sisuckatcs auto [a, b](p);
574*a618d5e0Sisuckatcs
575*a618d5e0Sisuckatcs clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}
576*a618d5e0Sisuckatcs clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}
577*a618d5e0Sisuckatcs
578*a618d5e0Sisuckatcs clang_analyzer_eval(b.i == 3); // expected-warning{{TRUE}}
579*a618d5e0Sisuckatcs clang_analyzer_eval(b.j == 4); // expected-warning{{TRUE}}
580*a618d5e0Sisuckatcs }
581