1 // RUN: %clang_analyze_cc1 -Wno-ignored-reference-qualifiers -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
3 #include "Inputs/system-header-simulator-cxx.h"
5 void clang_analyzer_eval(bool);
12 template <std::size_t I
, typename T
>
13 struct tuple_element
{
16 // The std::pair in our system header simulator is not tuple-like, so a tuple-like mock is created here
17 template <typename T1
, typename T2
>
22 template <typename T1
, typename T2
>
23 struct tuple_size
<mock_pair
<T1
, T2
>> {
24 static const std::size_t value
= 2;
27 template <typename T1
, typename T2
>
28 struct tuple_element
<0, mock_pair
<T1
, T2
>> {
32 template <typename T1
, typename T2
>
33 struct tuple_element
<1, mock_pair
<T1
, T2
>> {
37 template <std::size_t I
, class T
>
38 using tuple_element_t
= typename tuple_element
<I
, T
>::type
;
40 template <std::size_t I
, class T1
, class T2
>
41 constexpr std::tuple_element_t
<I
, std::mock_pair
<T1
, T2
>> &
42 get(std::mock_pair
<T1
, T2
> &p
) noexcept
{
49 template <std::size_t I
, class T1
, class T2
>
50 constexpr const std::tuple_element_t
<I
, std::mock_pair
<T1
, T2
>> &
51 get(const std::mock_pair
<T1
, T2
> &p
) noexcept
{
58 template <std::size_t I
, class T1
, class T2
>
59 constexpr std::tuple_element_t
<I
, std::mock_pair
<T1
, T2
>> &&
60 get(std::mock_pair
<T1
, T2
> &&p
) noexcept
{
63 return static_cast<std::tuple_element_t
<I
, std::mock_pair
<T1
, T2
>> &&>(p
.first
);
65 return static_cast<std::tuple_element_t
<I
, std::mock_pair
<T1
, T2
>> &&>(p
.second
);
68 template <std::size_t I
, class T1
, class T2
>
69 constexpr const std::tuple_element_t
<I
, std::mock_pair
<T1
, T2
>> &&
70 get(const std::mock_pair
<T1
, T2
> &&p
) noexcept
{
72 return static_cast<std::tuple_element_t
<I
, std::mock_pair
<T1
, T2
>> &&>(p
.first
);
74 return static_cast<std::tuple_element_t
<I
, std::mock_pair
<T1
, T2
>> &&>(p
.second
);
78 // A utility that generates a tuple-like struct with 2 fields
79 // of the same type. The fields are 'first' and 'second'
80 #define GENERATE_TUPLE_LIKE_STRUCT(name, element_type) \
83 element_type second; \
88 struct tuple_size<name> { \
89 static const std::size_t value = 2; \
92 template <std::size_t I> \
93 struct tuple_element<I, name> { \
94 using type = element_type; \
98 void non_user_defined_by_value(void) {
99 std::mock_pair
<int, int> p
= {1, 2};
103 clang_analyzer_eval(u
== 1); // expected-warning{{TRUE}}
104 clang_analyzer_eval(v
== 2); // expected-warning{{TRUE}}
110 clang_analyzer_eval(x
== 1); // expected-warning{{TRUE}}
111 clang_analyzer_eval(u
== 10); // expected-warning{{TRUE}}
113 clang_analyzer_eval(y
== 10); // expected-warning{{TRUE}}
114 clang_analyzer_eval(p
.first
== 1); // expected-warning{{TRUE}}
118 clang_analyzer_eval(u
== 10); // expected-warning{{TRUE}}
121 void non_user_defined_by_lref(void) {
122 std::mock_pair
<int, int> p
= {1, 2};
130 clang_analyzer_eval(x
== 1); // expected-warning{{TRUE}}
131 clang_analyzer_eval(u
== 10); // expected-warning{{TRUE}}
133 clang_analyzer_eval(y
== 10); // expected-warning{{TRUE}}
134 clang_analyzer_eval(p
.first
== 10); // expected-warning{{TRUE}}
136 clang_analyzer_eval(v
== 2); // expected-warning{{TRUE}}
137 clang_analyzer_eval(p
.second
== 2); // expected-warning{{TRUE}}
141 clang_analyzer_eval(u
== 5); // expected-warning{{TRUE}}
144 void non_user_defined_by_rref(void) {
145 std::mock_pair
<int, int> p
= {1, 2};
153 clang_analyzer_eval(x
== 1); // expected-warning{{TRUE}}
154 clang_analyzer_eval(u
== 10); // expected-warning{{TRUE}}
156 clang_analyzer_eval(y
== 10); // expected-warning{{TRUE}}
157 clang_analyzer_eval(p
.first
== 10); // expected-warning{{TRUE}}
159 clang_analyzer_eval(v
== 2); // expected-warning{{TRUE}}
160 clang_analyzer_eval(p
.second
== 2); // expected-warning{{TRUE}}
164 clang_analyzer_eval(u
== 5); // expected-warning{{TRUE}}
167 GENERATE_TUPLE_LIKE_STRUCT(Test
, int);
169 template <std::size_t I
>
180 void user_defined_get_val_by_val(void) {
184 clang_analyzer_eval(u
== 1); // expected-warning{{TRUE}}
190 clang_analyzer_eval(x
== 8); // expected-warning{{TRUE}}
192 clang_analyzer_eval(u
== 8); // expected-warning{{TRUE}}
193 clang_analyzer_eval(v
== 2); // expected-warning{{TRUE}}
195 clang_analyzer_eval(p
.first
== 1); // expected-warning{{TRUE}}
196 clang_analyzer_eval(p
.second
== 2); // expected-warning{{TRUE}}
200 clang_analyzer_eval(u
== 8); // expected-warning{{TRUE}}
201 clang_analyzer_eval(p
.first
== 5); // expected-warning{{TRUE}}
204 GENERATE_TUPLE_LIKE_STRUCT(Test2
, int);
206 template <std::size_t I
>
217 void user_defined_get_val_by_lref(void) {
222 clang_analyzer_eval(u
== 1); // expected-warning{{TRUE}}
223 clang_analyzer_eval(v
== 10); // expected-warning{{TRUE}}
229 clang_analyzer_eval(x
== 8); // expected-warning{{TRUE}}
231 clang_analyzer_eval(u
== 8); // expected-warning{{TRUE}}
232 clang_analyzer_eval(v
== 10); // expected-warning{{TRUE}}
234 clang_analyzer_eval(p
.first
== 20); // expected-warning{{TRUE}}
235 clang_analyzer_eval(p
.second
== 10); // expected-warning{{TRUE}}
239 clang_analyzer_eval(u
== 8); // expected-warning{{TRUE}}
240 clang_analyzer_eval(p
.first
== 5); // expected-warning{{TRUE}}
243 void user_defined_get_val_by_rref(void) {
248 clang_analyzer_eval(u
== 1); // expected-warning{{TRUE}}
249 clang_analyzer_eval(v
== 10); // expected-warning{{TRUE}}
255 clang_analyzer_eval(x
== 8); // expected-warning{{TRUE}}
257 clang_analyzer_eval(u
== 8); // expected-warning{{TRUE}}
258 clang_analyzer_eval(v
== 10); // expected-warning{{TRUE}}
260 clang_analyzer_eval(p
.first
== 20); // expected-warning{{TRUE}}
261 clang_analyzer_eval(p
.second
== 10); // expected-warning{{TRUE}}
265 clang_analyzer_eval(u
== 8); // expected-warning{{TRUE}}
266 clang_analyzer_eval(p
.first
== 5); // expected-warning{{TRUE}}
277 struct tuple_size
<MixedTest
> {
278 static const std::size_t value
= 3;
282 struct tuple_element
<0, MixedTest
> {
287 struct tuple_element
<1, MixedTest
> {
288 using type
= char &&;
292 struct tuple_element
<2, MixedTest
> {
296 template <std::size_t I
, typename T
>
297 using tuple_element_t
= typename tuple_element
<I
, T
>::type
;
301 template <std::size_t I
>
302 const std::tuple_element_t
<I
, MixedTest
> &get(const MixedTest
&t
) {}
305 const std::tuple_element_t
<0, MixedTest
> &get
<0>(const MixedTest
&t
) {
310 const std::tuple_element_t
<1, MixedTest
> &get
<1>(const MixedTest
&t
) {
315 const std::tuple_element_t
<2, MixedTest
> &get
<2>(const MixedTest
&t
) {
319 void mixed_type_cref(void) {
324 MixedTest m
{x
, std::move(y
), z
};
325 const auto &[a
, b
, c
] = m
;
327 clang_analyzer_eval(a
== 1); // expected-warning{{TRUE}}
328 clang_analyzer_eval(b
== 2); // expected-warning{{TRUE}}
329 clang_analyzer_eval(c
== 3); // expected-warning{{TRUE}}
331 clang_analyzer_eval(a
== 1); // expected-warning{{TRUE}}
332 clang_analyzer_eval(b
== 2); // expected-warning{{TRUE}}
333 clang_analyzer_eval(c
== 3); // expected-warning{{TRUE}}
336 template <std::size_t I
>
337 std::tuple_element_t
<I
, MixedTest
> &get(MixedTest
&t
) {}
340 std::tuple_element_t
<0, MixedTest
> &get
<0>(MixedTest
&t
) {
345 std::tuple_element_t
<1, MixedTest
> &get
<1>(MixedTest
&t
) {
350 std::tuple_element_t
<2, MixedTest
> &get
<2>(MixedTest
&t
) {
354 void mixed_type_lref(void) {
359 MixedTest m
{x
, std::move(y
), z
};
366 clang_analyzer_eval(get
<0>(m
) == 4); // expected-warning{{TRUE}}
367 clang_analyzer_eval(get
<1>(m
) == 5); // expected-warning{{TRUE}}
368 clang_analyzer_eval(get
<2>(m
) == 6); // expected-warning{{TRUE}}
370 clang_analyzer_eval(get
<0>(m
) == 4); // expected-warning{{TRUE}}
371 clang_analyzer_eval(get
<1>(m
) == 5); // expected-warning{{TRUE}}
372 clang_analyzer_eval(get
<2>(m
) == 6); // expected-warning{{TRUE}}
374 clang_analyzer_eval(z
== 6); // expected-warning{{TRUE}}
377 void mixed_type_rref(void) {
382 MixedTest m
{x
, std::move(y
), z
};
383 auto &&[a
, b
, c
] = m
;
389 clang_analyzer_eval(get
<0>(m
) == 4); // expected-warning{{TRUE}}
390 clang_analyzer_eval(get
<1>(m
) == 5); // expected-warning{{TRUE}}
391 clang_analyzer_eval(get
<2>(m
) == 6); // expected-warning{{TRUE}}
393 clang_analyzer_eval(get
<0>(m
) == 4); // expected-warning{{TRUE}}
394 clang_analyzer_eval(get
<1>(m
) == 5); // expected-warning{{TRUE}}
395 clang_analyzer_eval(get
<2>(m
) == 6); // expected-warning{{TRUE}}
397 clang_analyzer_eval(z
== 6); // expected-warning{{TRUE}}
402 std::mock_pair
<int &, int &> p
{i
, j
};
405 clang_analyzer_eval(a
== 1); // expected-warning{{TRUE}}
406 clang_analyzer_eval(b
== 2); // expected-warning{{TRUE}}
411 clang_analyzer_eval(p
.first
== 3); // expected-warning{{TRUE}}
412 clang_analyzer_eval(p
.second
== 4); // expected-warning{{TRUE}}
414 clang_analyzer_eval(a
== 3); // expected-warning{{TRUE}}
415 clang_analyzer_eval(b
== 4); // expected-warning{{TRUE}}
418 struct Small_Non_POD
{
423 void non_user_defined_small_non_pod_by_value(void) {
424 std::mock_pair
<Small_Non_POD
, Small_Non_POD
> p
{{1, 2}, {1, 2}};
428 clang_analyzer_eval(a
.i
== 1); // expected-warning{{TRUE}}
429 clang_analyzer_eval(a
.j
== 2); // expected-warning{{TRUE}}
431 clang_analyzer_eval(b
.i
== 1); // expected-warning{{TRUE}}
432 clang_analyzer_eval(b
.j
== 2); // expected-warning{{TRUE}}
440 clang_analyzer_eval(a
.i
== 3); // expected-warning{{TRUE}}
441 clang_analyzer_eval(a
.j
== 4); // expected-warning{{TRUE}}
443 clang_analyzer_eval(b
.i
== 5); // expected-warning{{TRUE}}
444 clang_analyzer_eval(b
.j
== 6); // expected-warning{{TRUE}}
446 clang_analyzer_eval(p
.first
.i
== 1); // expected-warning{{TRUE}}
447 clang_analyzer_eval(p
.first
.j
== 2); // expected-warning{{TRUE}}
449 clang_analyzer_eval(p
.second
.i
== 1); // expected-warning{{TRUE}}
450 clang_analyzer_eval(p
.second
.j
== 2); // expected-warning{{TRUE}}
453 void non_user_defined_small_non_pod_by_lref(void) {
454 std::mock_pair
<Small_Non_POD
, Small_Non_POD
> p
{{1, 2}, {1, 2}};
458 clang_analyzer_eval(a
.i
== 1); // expected-warning{{TRUE}}
459 clang_analyzer_eval(a
.j
== 2); // expected-warning{{TRUE}}
461 clang_analyzer_eval(b
.i
== 1); // expected-warning{{TRUE}}
462 clang_analyzer_eval(b
.j
== 2); // expected-warning{{TRUE}}
470 clang_analyzer_eval(a
.i
== 3); // expected-warning{{TRUE}}
471 clang_analyzer_eval(a
.j
== 4); // expected-warning{{TRUE}}
473 clang_analyzer_eval(b
.i
== 5); // expected-warning{{TRUE}}
474 clang_analyzer_eval(b
.j
== 6); // expected-warning{{TRUE}}
476 clang_analyzer_eval(p
.first
.i
== 3); // expected-warning{{TRUE}}
477 clang_analyzer_eval(p
.first
.j
== 4); // expected-warning{{TRUE}}
479 clang_analyzer_eval(p
.second
.i
== 5); // expected-warning{{TRUE}}
480 clang_analyzer_eval(p
.second
.j
== 6); // expected-warning{{TRUE}}
483 void non_user_defined_small_non_pod_by_rref(void) {
484 std::mock_pair
<Small_Non_POD
, Small_Non_POD
> p
{{1, 2}, {1, 2}};
488 clang_analyzer_eval(a
.i
== 1); // expected-warning{{TRUE}}
489 clang_analyzer_eval(a
.j
== 2); // expected-warning{{TRUE}}
491 clang_analyzer_eval(b
.i
== 1); // expected-warning{{TRUE}}
492 clang_analyzer_eval(b
.j
== 2); // expected-warning{{TRUE}}
500 clang_analyzer_eval(a
.i
== 3); // expected-warning{{TRUE}}
501 clang_analyzer_eval(a
.j
== 4); // expected-warning{{TRUE}}
503 clang_analyzer_eval(b
.i
== 5); // expected-warning{{TRUE}}
504 clang_analyzer_eval(b
.j
== 6); // expected-warning{{TRUE}}
506 clang_analyzer_eval(p
.first
.i
== 3); // expected-warning{{TRUE}}
507 clang_analyzer_eval(p
.first
.j
== 4); // expected-warning{{TRUE}}
509 clang_analyzer_eval(p
.second
.i
== 5); // expected-warning{{TRUE}}
510 clang_analyzer_eval(p
.second
.j
== 6); // expected-warning{{TRUE}}
513 GENERATE_TUPLE_LIKE_STRUCT(Uninit
, int);
514 template <std::size_t I
>
515 int &get(Uninit
&&t
) {
523 void uninit_a(void) {
528 int x
= a
; // expected-warning{{Assigned value is garbage or undefined}}
531 void uninit_b(void) {
536 int x
= b
; // expected-warning{{Assigned value is garbage or undefined}}
539 GENERATE_TUPLE_LIKE_STRUCT(UninitCall
, int);
540 template <std::size_t I
>
541 int get(UninitCall t
) {
549 void uninit_call(void) {
555 // expected-warning@543{{Undefined or garbage value returned to caller}}
559 std::mock_pair
<Small_Non_POD
, Small_Non_POD
> p
{{1, 2}, {3, 4}};
563 clang_analyzer_eval(a
.i
== 1); // expected-warning{{TRUE}}
564 clang_analyzer_eval(a
.j
== 2); // expected-warning{{TRUE}}
566 clang_analyzer_eval(b
.i
== 3); // expected-warning{{TRUE}}
567 clang_analyzer_eval(b
.j
== 4); // expected-warning{{TRUE}}
571 std::mock_pair
<Small_Non_POD
, Small_Non_POD
> p
{{1, 2}, {3, 4}};
575 clang_analyzer_eval(a
.i
== 1); // expected-warning{{TRUE}}
576 clang_analyzer_eval(a
.j
== 2); // expected-warning{{TRUE}}
578 clang_analyzer_eval(b
.i
== 3); // expected-warning{{TRUE}}
579 clang_analyzer_eval(b
.j
== 4); // expected-warning{{TRUE}}