1 // RUN: %clang_analyze_cc1 -std=c++17 -analyzer-checker=core,deadcode -verify %s
3 typedef unsigned long size_t;
5 // Machinery required for custom structured bindings decomposition.
7 template <class T
> class tuple_size
;
9 constexpr size_t tuple_size_v
= tuple_size
<T
>::value
;
10 template <size_t I
, class T
> class tuple_element
;
12 template<class T
, T v
>
13 struct integral_constant
{
14 static constexpr T value
= v
;
16 typedef integral_constant type
;
17 constexpr operator value_type() const noexcept
{ return value
; }
24 S(int a
, double b
) : a(a
), b(b
) {};
30 const auto [a
, b
] = GetNumbers(); // no-warning
34 void no_warning_on_copy(S s
) {
35 // Copy constructor might have side effects.
36 const auto [a
, b
] = s
; // no-warning
40 int unused_binding_ignored() {
41 const auto [a
, b
] = GetNumbers(); // expected-warning{{Value stored to '[a, b]' during its initialization is never read}}
45 int unused_binding_liveness_required() {
46 auto [a2
, b2
] = GetNumbers(); // expected-warning{{Value stored to '[a2, b2]' during its initialization is never read}}
52 int kill_one_binding() {
53 auto [a
, b
] = GetNumbers(); // no-warning
59 int kill_one_binding2() {
60 auto [a
, b
] = GetNumbers(); // expected-warning{{Value stored to '[a, b]' during its initialization is never read}}
65 void use_const_reference_bindings() {
66 const auto &[a
, b
] = GetNumbers(); // no-warning
69 void use_reference_bindings() {
71 auto &[a
, b
] = s
; // no-warning
75 int read_through_pointer() {
76 auto [a
, b
] = GetNumbers(); // no-warning
81 auto [globalA
, globalB
] = GetNumbers(); // no-warning, globals
82 auto [globalC
, globalD
] = GetNumbers(); // no-warning, globals
85 globalA
= 300; // no-warning
95 if constexpr (N
== 0) return a
;
96 else if constexpr (N
== 1) return b
;
102 struct tuple_size
<Mytuple
>
103 : std::integral_constant
<size_t, 2> {};
106 struct tuple_element
<N
, Mytuple
> {
111 void no_warning_on_tuple_types_copy(Mytuple t
) {
112 auto [a
, b
] = t
; // no-warning
115 Mytuple
getMytuple();
117 void deconstruct_tuple_types_warning() {
118 // The initializers reference the decomposed region, so the warning is not reported
119 // FIXME: ideally we want to ignore that the initializers reference the decomposed region, and report the warning,
120 // though the first step towards that is to handle DeadCode if the initializer is CXXConstructExpr.
121 auto [a
, b
] = getMytuple(); // no-warning
124 int deconstruct_tuple_types_no_warning() {
125 auto [a
, b
] = getMytuple(); // no-warning