1 // RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx17 -fcxx-exceptions
2 // RUN: %clang_cc1 -std=c++2b %s -verify=expected,cxx2b -fcxx-exceptions
3 // RUN: not %clang_cc1 -std=c++17 %s -emit-llvm-only -fcxx-exceptions
5 struct S
{ int a
, b
, c
; };
7 // A simple-declaration can be a decompsition declaration.
9 auto [a_x
, b_x
, c_x
] = S();
14 for (auto [a
, b
, c
] = S();;) {}
15 if (auto [a
, b
, c
] = S(); true) {}
16 switch (auto [a
, b
, c
] = S(); 0) { case 0:; }
21 // A for-range-declaration can be a decomposition declaration.
22 namespace ForRangeDecl
{
25 for (auto [a
, b
, c
] : arr
) {
30 // Other kinds of declaration cannot.
32 // A parameter-declaration is not a simple-declaration.
33 // This parses as an array declaration.
34 void f(auto [a
, b
, c
]); // cxx17-error {{'auto' not allowed in function prototype}} expected-error {{'a'}}
37 // A condition is allowed as a Clang extension.
38 // See commentary in test/Parser/decomposed-condition.cpp
39 for (; auto [a
, b
, c
] = S(); ) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
40 if (auto [a
, b
, c
] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
41 if (int n
; auto [a
, b
, c
] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
42 switch (auto [a
, b
, c
] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('S' invalid)}}
43 switch (int n
; auto [a
, b
, c
] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('S' invalid)}}
44 while (auto [a
, b
, c
] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
46 // An exception-declaration is not a simple-declaration.
48 catch (auto [a
, b
, c
]) {} // expected-error {{'auto' not allowed in exception declaration}} expected-error {{'a'}}
51 // A member-declaration is not a simple-declaration.
53 auto [a
, b
, c
] = S(); // expected-error {{not permitted in this context}}
54 static auto [a
, b
, c
] = S(); // expected-error {{not permitted in this context}}
58 namespace GoodSpecifiers
{
61 const volatile auto &[a
] = n
; // cxx2b-warning {{volatile qualifier in structured binding declaration is deprecated}}
65 namespace BadSpecifiers
{
68 struct S
{ int n
; } s
;
70 // storage-class-specifiers
71 static auto &[a
] = n
; // cxx17-warning {{declared 'static' is a C++20 extension}}
72 thread_local
auto &[b
] = n
; // cxx17-warning {{declared 'thread_local' is a C++20 extension}}
73 extern auto &[c
] = n
; // expected-error {{cannot be declared 'extern'}} expected-error {{declaration of block scope identifier with linkage cannot have an initializer}}
75 mutable auto &[d
] = n
; // expected-error {{not permitted in this context}}
77 // function-specifiers
78 virtual auto &[e
] = n
; // expected-error {{not permitted in this context}}
79 explicit auto &[f
] = n
; // expected-error {{not permitted in this context}}
81 // misc decl-specifiers
82 friend auto &[g
] = n
; // expected-error {{'auto' not allowed}} expected-error {{friends can only be classes or functions}}
84 typedef auto &[h
] = n
; // expected-error {{cannot be declared 'typedef'}}
85 constexpr auto &[i
] = n
; // expected-error {{cannot be declared 'constexpr'}}
88 static constexpr inline thread_local
auto &[j1
] = n
; // expected-error {{cannot be declared with 'constexpr inline' specifiers}}
89 static thread_local
auto &[j2
] = n
; // cxx17-warning {{declared with 'static thread_local' specifiers is a C++20 extension}}
91 inline auto &[k
] = n
; // expected-error {{cannot be declared 'inline'}}
94 auto ([c
]) = s
; // expected-error {{decomposition declaration cannot be declared with parentheses}}
96 // defining-type-specifiers other than cv-qualifiers and 'auto'
97 S
[a
] = s
; // expected-error {{cannot be declared with type 'S'}}
98 decltype(auto) [b
] = s
; // expected-error {{cannot be declared with type 'decltype(auto)'}}
99 auto ([c2
]) = s
; // cxx17-error {{decomposition declaration cannot be declared with parenthese}} \
100 // cxx2b-error {{use of undeclared identifier 'c2'}} \
101 // cxx2b-error {{expected body of lambda expression}} \
103 // FIXME: This error is not very good.
104 auto [d
]() = s
; // expected-error {{expected ';'}} expected-error {{expected expression}}
105 auto [e
][1] = s
; // expected-error {{expected ';'}} expected-error {{requires an initializer}}
107 // FIXME: This should fire the 'misplaced array declarator' diagnostic.
108 int [K
] arr
= {0}; // expected-error {{expected ';'}} expected-error {{cannot be declared with type 'int'}} expected-error {{decomposition declaration '[K]' requires an initializer}}
109 int [5] arr
= {0}; // expected-error {{place the brackets after the name}}
111 auto *[f
] = s
; // expected-error {{cannot be declared with type 'auto *'}} expected-error {{incompatible initializer}}
112 auto S::*[g
] = s
; // expected-error {{cannot be declared with type 'auto BadSpecifiers::S::*'}} expected-error {{incompatible initializer}}
114 // ref-qualifiers are OK.
118 // attributes are OK.
119 [[]] auto [ok_3
] = s
;
120 alignas(S
) auto [ok_4
] = s
;
122 // ... but not after the identifier or declarator.
123 // FIXME: These errors are not very good.
124 auto [bad_attr_1
[[]]] = s
; // expected-error {{attribute list cannot appear here}} expected-error 2{{}}
125 auto [bad_attr_2
] [[]] = s
; // expected-error {{expected ';'}} expected-error {{}}
129 namespace MultiDeclarator
{
132 auto [a
] = s
, [b
] = s
; // expected-error {{must be the only declaration}}
133 auto [c
] = s
, d
= s
; // expected-error {{must be the only declaration}}
134 auto e
= s
, [f
] = s
; // expected-error {{must be the only declaration}}
135 auto g
= s
, h
= s
, i
= s
, [j
] = s
; // expected-error {{must be the only declaration}}
141 // FIXME: There's no actual rule against this...
142 template<typename T
> auto [a
, b
, c
] = n
; // expected-error {{decomposition declaration template not supported}}
149 auto &[bad1
]; // expected-error {{decomposition declaration '[bad1]' requires an initializer}}
150 const auto &[bad2
](S
{}, S
{}); // expected-error {{initializer for variable '[bad2]' with type 'const auto &' contains multiple expressions}}
151 const auto &[bad3
](); // expected-error {{expected expression}}
153 auto &&[good2
] = S
{};
154 const auto &[good3
](S
{});
155 S
[goodish3
] = { 4 }; // expected-error {{cannot be declared with type 'S'}}
156 S
[goodish4
] { 4 }; // expected-error {{cannot be declared with type 'S'}}