1 // RUN: %clang_cc1 -std=c++17 %s -triple x86_64-unknown-linux-gnu -verify=expected,cxx17,pre2c -fcxx-exceptions
2 // RUN: %clang_cc1 -std=c++2b %s -triple x86_64-unknown-linux-gnu -verify=expected,cxx2b,pre2c,post2b -fcxx-exceptions
3 // RUN: %clang_cc1 -std=c++2c %s -triple x86_64-unknown-linux-gnu -verify=expected,cxx2c,post2b -fcxx-exceptions
4 // RUN: not %clang_cc1 -std=c++17 %s -triple x86_64-unknown-linux-gnu -emit-llvm-only -fcxx-exceptions
6 struct S
{ int a
, b
, c
; };
8 // A simple-declaration can be a decompsition declaration.
10 auto [a_x
, b_x
, c_x
] = S();
15 for (auto [a
, b
, c
] = S();;) {}
16 if (auto [a
, b
, c
] = S(); true) {}
17 switch (auto [a
, b
, c
] = S(); 0) { case 0:; }
22 // A for-range-declaration can be a decomposition declaration.
23 namespace ForRangeDecl
{
26 for (auto [a
, b
, c
] : arr
) {
31 // Other kinds of declaration cannot.
33 // A parameter-declaration is not a simple-declaration.
34 // This parses as an array declaration.
35 void f(auto [a
, b
, c
]); // cxx17-error {{'auto' not allowed in function prototype}} expected-error {{'a'}}
38 // A condition is allowed as a Clang extension.
39 // See commentary in test/Parser/decomposed-condition.cpp
40 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'}}
41 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'}}
42 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'}}
43 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)}}
44 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)}}
45 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'}}
47 // An exception-declaration is not a simple-declaration.
49 catch (auto [a
, b
, c
]) {} // expected-error {{'auto' not allowed in exception declaration}} expected-error {{'a'}}
52 // A member-declaration is not a simple-declaration.
54 auto [a
, b
, c
] = S(); // expected-error {{not permitted in this context}}
55 static auto [a
, b
, c
] = S(); // expected-error {{not permitted in this context}}
59 namespace GoodSpecifiers
{
62 const volatile auto &[a
] = n
; // post2b-warning {{volatile qualifier in structured binding declaration is deprecated}}
66 namespace BadSpecifiers
{
69 struct S
{ int n
; } s
;
71 // storage-class-specifiers
72 static auto &[a
] = n
; // cxx17-warning {{declared 'static' is a C++20 extension}}
73 thread_local
auto &[b
] = n
; // cxx17-warning {{declared 'thread_local' is a C++20 extension}}
74 extern auto &[c
] = n
; // expected-error {{cannot be declared 'extern'}} expected-error {{declaration of block scope identifier with linkage cannot have an initializer}}
76 mutable auto &[d
] = n
; // expected-error {{not permitted in this context}}
78 // function-specifiers
79 virtual auto &[e
] = n
; // expected-error {{not permitted in this context}}
80 explicit auto &[f
] = n
; // expected-error {{not permitted in this context}}
82 // misc decl-specifiers
83 friend auto &[g
] = n
; // expected-error {{'auto' not allowed}} expected-error {{friends can only be classes or functions}}
85 typedef auto &[h
] = n
; // expected-error {{cannot be declared 'typedef'}}
86 constexpr auto &[i
] = n
; // expected-error {{cannot be declared 'constexpr'}}
89 static constexpr inline thread_local
auto &[j1
] = n
; // expected-error {{cannot be declared with 'constexpr inline' specifiers}}
90 static thread_local
auto &[j2
] = n
; // cxx17-warning {{declared with 'static thread_local' specifiers is a C++20 extension}}
92 inline auto &[k
] = n
; // expected-error {{cannot be declared 'inline'}}
95 auto ([c
]) = s
; // expected-error {{decomposition declaration cannot be declared with parentheses}}
97 // defining-type-specifiers other than cv-qualifiers and 'auto'
98 S
[a
] = s
; // expected-error {{cannot be declared with type 'S'}}
99 decltype(auto) [b
] = s
; // expected-error {{cannot be declared with type 'decltype(auto)'}}
100 auto ([c2
]) = s
; // cxx17-error {{decomposition declaration cannot be declared with parenthese}} \
101 // post2b-error {{use of undeclared identifier 'c2'}} \
102 // post2b-error {{expected body of lambda expression}} \
104 // FIXME: This error is not very good.
105 auto [d
]() = s
; // expected-error {{expected ';'}} expected-error {{expected expression}}
106 auto [e
][1] = s
; // expected-error {{expected ';'}} expected-error {{requires an initializer}}
108 // FIXME: This should fire the 'misplaced array declarator' diagnostic.
109 int [K
] arr
= {0}; // expected-error {{expected ';'}} expected-error {{cannot be declared with type 'int'}} expected-error {{decomposition declaration '[K]' requires an initializer}}
110 int [5] arr
= {0}; // expected-error {{place the brackets after the name}}
112 auto *[f
] = s
; // expected-error {{cannot be declared with type 'auto *'}} expected-error {{incompatible initializer}}
113 auto S::*[g
] = s
; // expected-error {{cannot be declared with type 'auto BadSpecifiers::S::*'}} expected-error {{incompatible initializer}}
115 // ref-qualifiers are OK.
119 // attributes are OK.
120 [[]] auto [ok_3
] = s
;
121 alignas(S
) auto [ok_4
] = s
;
123 auto [bad_attr_2
] [[]] = s
; // expected-error {{expected ';'}} expected-error {{}}
127 namespace MultiDeclarator
{
130 auto [a
] = s
, [b
] = s
; // expected-error {{must be the only declaration}}
131 auto [c
] = s
, d
= s
; // expected-error {{must be the only declaration}}
132 auto e
= s
, [f
] = s
; // expected-error {{must be the only declaration}}
133 auto g
= s
, h
= s
, i
= s
, [j
] = s
; // expected-error {{must be the only declaration}}
139 // FIXME: There's no actual rule against this...
140 template<typename T
> auto [a
, b
, c
] = n
; // expected-error {{decomposition declaration template not supported}}
147 auto &[bad1
]; // expected-error {{decomposition declaration '[bad1]' requires an initializer}}
148 const auto &[bad2
](S
{}, S
{}); // expected-error {{initializer for variable '[bad2]' with type 'const auto &' contains multiple expressions}}
149 const auto &[bad3
](); // expected-error {{expected expression}}
151 auto &&[good2
] = S
{};
152 const auto &[good3
](S
{});
153 S
[goodish3
] = { 4 }; // expected-error {{cannot be declared with type 'S'}}
154 S
[goodish4
] { 4 }; // expected-error {{cannot be declared with type 'S'}}
159 namespace attributes
{
167 auto [[]] = S
{0}; // expected-error {{expected unqualified-id}}
168 auto [ alignas(42) a
, foo
] = S
{0}; // expected-error {{an attribute list cannot appear here}}
169 auto [ c
, [[]] d
] = S
{0}; // expected-error {{an attribute list cannot appear here}}
170 auto [ e
, alignas(42) f
] = S
{0}; // expected-error {{an attribute list cannot appear here}}
174 auto [ a
alignas(42) [[]], b
alignas(42) [[]]] = S
{0}; // expected-error 2{{'alignas' attribute only applies to variables, data members and tag types}} \
175 // pre2c-warning 2{{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}
176 auto [ c
[[]] alignas(42), d
[[]] alignas(42) [[]]] = S
{0}; // expected-error 2{{'alignas' attribute only applies to variables, data members and tag types}} \
177 // pre2c-warning 2{{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}
181 auto [G1
[[deprecated
]], G2
[[deprecated
]]] = S
{42}; // #deprecated-here
182 // pre2c-warning@-1 2{{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}
185 return G1
+ G2
; // expected-warning {{'G1' is deprecated}} expected-note@#deprecated-here {{here}} \
186 // expected-warning {{'G2' is deprecated}} expected-note@#deprecated-here {{here}}
189 void invalid_attributes() {
190 // pre2c-warning@+1 {{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}
191 auto [a
alignas(42) // expected-error {{'alignas' attribute only applies to variables, data members and tag types}}
192 [[assume(true), // expected-error {{'assume' attribute cannot be applied to a declaration}}
193 carries_dependency
, // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}
194 fallthrough
, // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
195 likely
, // expected-error {{'likely' attribute cannot be applied to a declaration}}
196 unlikely
, // expected-error {{'unlikely' attribute cannot be applied to a declaration}}
197 nodiscard
, // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, function pointers, and typedefs}}
198 noreturn
, // expected-error {{'noreturn' attribute only applies to functions}}
199 no_unique_address
]], // expected-error {{'no_unique_address' attribute only applies to non-bit-field non-static data members}}