[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Parser / cxx1z-decomposition.cpp
blob4b17f72effb0f87f73d54404eee7bbc93dda79e2
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.
9 namespace SimpleDecl {
10 auto [a_x, b_x, c_x] = S();
12 void f(S s) {
13 auto [a, b, c] = 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 {
24 extern S arr[10];
25 void h() {
26 for (auto [a, b, c] : arr) {
31 // Other kinds of declaration cannot.
32 namespace OtherDecl {
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'}}
37 void g() {
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.
48 try {}
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.
53 class A {
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 {
60 void f() {
61 int n[1];
62 const volatile auto &[a] = n; // post2b-warning {{volatile qualifier in structured binding declaration is deprecated}}
66 namespace BadSpecifiers {
67 typedef int I1[1];
68 I1 n;
69 struct S { int n; } s;
70 void f() {
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}}
75 struct S {
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'}}
94 const int K = 5;
95 auto ([c]) = s; // expected-error {{decomposition declaration cannot be declared with parentheses}}
96 void g() {
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.
116 auto &&[ok_1] = S();
117 auto &[ok_2] = s;
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 {
128 struct S { int n; };
129 void f(S s) {
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}}
137 namespace Template {
138 int n[3];
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}}
143 namespace Init {
144 void f() {
145 int arr[1];
146 struct S { int n; };
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}}
150 auto &[good1] = arr;
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 {
161 struct S{
162 int a;
163 int b = 0;
166 void err() {
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}}
173 void ok() {
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}}
184 int test() {
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}}
200 b] = S{0};