1 // RUN: %clang_cc1 -std=c++17 -Wc++20-extensions -verify=expected %s
2 // RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -verify=expected %s
4 void use_from_own_init() {
5 auto [a
] = a
; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}}
12 auto [] = a0
; // expected-warning {{does not allow a decomposition group to be empty}}
13 auto [v1
] = a0
; // expected-error {{type 'struct A0' decomposes into 0 elements, but 1 name was provided}}
14 auto [] = a1
; // expected-error {{type 'int[1]' decomposes into 1 element, but no names were provided}} expected-warning {{empty}}
16 auto [v3
, v4
] = a1
; // expected-error {{type 'int[1]' decomposes into 1 element, but 2 names were provided}}
17 auto [] = a2
; // expected-error {{type 'int[2]' decomposes into 2 elements, but no names were provided}} expected-warning {{empty}}
18 auto [v5
] = a2
; // expected-error {{type 'int[2]' decomposes into 2 elements, but only 1 name was provided}}
20 auto [v8
, v9
, v10
] = a2
; // expected-error {{type 'int[2]' decomposes into 2 elements, but 3 names were provided}}
23 // As a Clang extension, _Complex can be decomposed.
24 float decompose_complex(_Complex
float cf
) {
25 static _Complex
float scf
;
26 auto &[sre
, sim
] = scf
;
27 // ok, this is references initialized by constant expressions all the way down
28 static_assert(&sre
== &__real scf
);
29 static_assert(&sim
== &__imag scf
);
35 // As a Clang extension, vector types can be decomposed.
36 typedef float vf3
__attribute__((ext_vector_type(3)));
37 float decompose_vector(vf3 v
) {
39 auto *p
= &x
; // expected-error {{address of vector element requested}}
43 struct S
{ int a
, b
; };
44 constexpr int f(S s
) {
48 static_assert(f({1, 2}) == 12);
50 constexpr bool g(S
&&s
) {
52 return &a
== &s
.a
&& &b
== &s
.b
&& &a
!= &b
;
54 static_assert(g({1, 2}));
60 int a
: 1; // expected-note 2{{bit-field is declared here}}
64 auto [outer1
, outer2
] = S1
{1, 2};
65 auto [outerbit1
, outerbit2
] = S1
{1, 2}; // expected-note {{declared here}}
68 struct S
{ int a
= outer1
; };
69 auto [n
] = S(); // expected-note 3{{'n' declared here}}
72 int f() { return n
; } // expected-error {{reference to local binding 'n' declared in enclosing function 'enclosing'}}
75 (void)[&] { return n
; }; // expected-warning {{C++20}}
76 (void)[n
] { return n
; }; // expected-warning {{C++20}}
78 static auto [m
] = S(); // expected-note {{'m' declared here}} \
79 // expected-warning {{C++20}}
81 struct R
{ int f() { return m
; } };
82 (void) [&] { return m
; };
83 (void)[m
]{}; // expected-error {{'m' cannot be captured because it does not have automatic storage duration}}
85 (void)[outerbit1
]{}; // expected-error {{'outerbit1' cannot be captured because it does not have automatic storage duration}}
87 auto [bit
, var
] = S2
{-1, 1}; // expected-note 2{{'bit' declared here}}
89 (void)[&bit
] { // expected-error {{non-const reference cannot bind to bit-field 'a'}} \
90 // expected-warning {{C++20}}
94 union { // expected-note {{declared here}}
98 (void)[&] { return bit
+ u
; } // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}} \
99 // expected-error {{non-const reference cannot bind to bit-field 'a'}} \
100 // expected-warning {{C++20}}
105 struct { int a
: 3, : 4, b
: 5; } a
;
107 auto &[p
, q
, r
] = a
; // expected-error-re {{type 'struct (unnamed struct at {{.*}})' decomposes into 2 elements, but 3 names were provided}}
112 for (auto[a
, b
] : x
) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
117 for (auto[c
] : y
) { // expected-error {{cannot decompose non-class, non-array type 'int'}}
122 int error_recovery() {
123 auto [foobar
]; // expected-error {{requires an initializer}}
124 return foobar_
; // expected-error {{undeclared identifier 'foobar_'}}
128 template <class T
> void dependent_foreach(T t
) {
129 for (auto [a
,b
,c
] : t
)
135 void f() { static auto [a
] = *this; } // expected-warning {{C++20}}
138 namespace instantiate_template
{
140 template <typename T1
, typename T2
>
146 const pair
<int, int> &f1();
149 const auto &[a
, b
] = f1();
153 } // namespace instantiate_template
158 auto [a
] = // expected-error {{cannot decompose lambda closure type}}
159 [n
] {}; // expected-note {{lambda expression}}
162 auto [] = []{}; // expected-warning {{ISO C++17 does not allow a decomposition group to be empty}}
166 auto a
= [=](auto &self
) { // expected-note {{lambda expression}}
167 auto &[capture
] = self
; // expected-error {{cannot decompose lambda closure type}}
171 return a(a
); // expected-note {{in instantiation of}}
176 struct A
: decltype(x
) {
179 auto &&[r
] = A
{x
, 0}; // OK (presumably), non-capturing lambda has no non-static data members
186 struct A
: decltype(x
) {
189 auto &&[r
] = A
{x
, 0}; // expected-error-re {{cannot decompose class type 'A': both it and its base class 'decltype(x)' (aka '(lambda {{.*}})') have non-static data members}}
195 struct A
: decltype(x
) {};
196 auto &&[] = A
{x
}; // expected-warning {{ISO C++17 does not allow a decomposition group to be empty}}
200 // FIXME: by-value array copies