blob: 9cbe70e3c69bdfa3493c8db67844fb05d6504bf7 [file] [log] [blame]
Richard Smithbdb84f32016-07-22 23:36:59 +00001// RUN: %clang_cc1 -std=c++1z %s -verify -fcxx-exceptions
2
3struct S { int a, b, c; };
4
5// A simple-declaration can be a decompsition declaration.
6namespace SimpleDecl {
7 auto [a_x, b_x, c_x] = S();
8
9 void f(S s) {
10 auto [a, b, c] = S();
11 {
12 for (auto [a, b, c] = S();;) {}
13 if (auto [a, b, c] = S(); true) {}
14 switch (auto [a, b, c] = S(); 0) { case 0:; }
15 }
16 }
17}
18
19// A for-range-declaration can be a decomposition declaration.
20namespace ForRangeDecl {
21 extern S arr[10];
22 void h() {
23 for (auto [a, b, c] : arr) {
24 }
25 }
26}
27
28// Other kinds of declaration cannot.
29namespace OtherDecl {
30 // A parameter-declaration is not a simple-declaration.
31 // This parses as an array declaration.
32 void f(auto [a, b, c]); // expected-error {{'auto' not allowed in function prototype}} expected-error {{'a'}}
33
34 void g() {
35 // A condition is not a simple-declaration.
36 for (; auto [a, b, c] = S(); ) {} // expected-error {{not permitted in this context}}
37 if (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
38 if (int n; auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
39 switch (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
40 switch (int n; auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
41 while (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
42
43 // An exception-declaration is not a simple-declaration.
44 try {}
45 catch (auto [a, b, c]) {} // expected-error {{'auto' not allowed in exception declaration}} expected-error {{'a'}}
46 }
47
48 // A member-declaration is not a simple-declaration.
49 class A {
50 auto [a, b, c] = S(); // expected-error {{not permitted in this context}}
51 static auto [a, b, c] = S(); // expected-error {{not permitted in this context}}
52 };
53}
54
55namespace GoodSpecifiers {
56 void f() {
57 int n[1];
58 const volatile auto &[a] = n;
59 }
60}
61
62namespace BadSpecifiers {
63 typedef int I1[1];
64 I1 n;
65 struct S { int n; } s;
66 void f() {
67 // storage-class-specifiers
68 static auto &[a] = n; // expected-error {{cannot be declared 'static'}}
69 thread_local auto &[b] = n; // expected-error {{cannot be declared 'thread_local'}}
Richard Smith7873de02016-08-11 22:25:46 +000070 extern auto &[c] = n; // expected-error {{cannot be declared 'extern'}} expected-error {{cannot have an initializer}}
Richard Smithbdb84f32016-07-22 23:36:59 +000071 struct S {
72 mutable auto &[d] = n; // expected-error {{not permitted in this context}}
73
74 // function-specifiers
75 virtual auto &[e] = n; // expected-error {{not permitted in this context}}
76 explicit auto &[f] = n; // expected-error {{not permitted in this context}}
77
78 // misc decl-specifiers
79 friend auto &[g] = n; // expected-error {{'auto' not allowed}} expected-error {{friends can only be classes or functions}}
80 };
81 typedef auto &[h] = n; // expected-error {{cannot be declared 'typedef'}}
82 constexpr auto &[i] = n; // expected-error {{cannot be declared 'constexpr'}}
83
84 static constexpr thread_local auto &[j] = n; // expected-error {{cannot be declared with 'static thread_local constexpr' specifiers}}
85 }
86 inline auto &[k] = n; // expected-error {{cannot be declared 'inline'}}
87
88 const int K = 5;
89 void g() {
90 // defining-type-specifiers other than cv-qualifiers and 'auto'
91 S [a] = s; // expected-error {{cannot be declared with type 'BadSpecifiers::S'}}
92 decltype(auto) [b] = s; // expected-error {{cannot be declared with type 'decltype(auto)'}}
93 auto ([c]) = s; // expected-error {{cannot be declared with parentheses}}
94
95 // FIXME: This error is not very good.
96 auto [d]() = s; // expected-error {{expected ';'}} expected-error {{expected expression}}
97 auto [e][1] = s; // expected-error {{expected ';'}} expected-error {{requires an initializer}}
98
99 // FIXME: This should fire the 'misplaced array declarator' diagnostic.
Richard Smith7873de02016-08-11 22:25:46 +0000100 int [K] arr = {0}; // expected-error {{expected ';'}} expected-error {{cannot be declared with type 'int'}} expected-error {{decomposition declaration '[K]' requires an initializer}}
Richard Smithbdb84f32016-07-22 23:36:59 +0000101 int [5] arr = {0}; // expected-error {{place the brackets after the name}}
102
103 auto *[f] = s; // expected-error {{cannot be declared with type 'auto *'}} expected-error {{incompatible initializer}}
104 auto S::*[g] = s; // expected-error {{cannot be declared with type 'auto BadSpecifiers::S::*'}} expected-error {{incompatible initializer}}
105
106 // ref-qualifiers are OK.
107 auto &&[ok_1] = S();
108 auto &[ok_2] = s;
109
110 // attributes are OK.
111 [[]] auto [ok_3] = s;
112 alignas(S) auto [ok_4] = s;
113
114 // ... but not after the identifier or declarator.
115 // FIXME: These errors are not very good.
116 auto [bad_attr_1 [[]]] = s; // expected-error {{attribute list cannot appear here}} expected-error 2{{}}
117 auto [bad_attr_2] [[]] = s; // expected-error {{expected ';'}} expected-error {{}}
118 }
119}
120
121namespace MultiDeclarator {
122 struct S { int n; };
123 void f(S s) {
124 auto [a] = s, [b] = s; // expected-error {{must be the only declaration}}
125 auto [c] = s, d = s; // expected-error {{must be the only declaration}}
126 auto e = s, [f] = s; // expected-error {{must be the only declaration}}
127 auto g = s, h = s, i = s, [j] = s; // expected-error {{must be the only declaration}}
128 }
129}
130
131namespace Template {
132 int n[3];
133 // FIXME: There's no actual rule against this...
134 template<typename T> auto [a, b, c] = n; // expected-error {{decomposition declaration template not supported}}
135}
Richard Smith7873de02016-08-11 22:25:46 +0000136
137namespace Init {
138 void f() {
139 int arr[1];
140 struct S { int n; };
141 auto &[bad1]; // expected-error {{decomposition declaration '[bad1]' requires an initializer}}
Richard Smith4b46cb92016-12-09 22:56:20 +0000142 const auto &[bad2](S{}, S{}); // expected-error {{initializer for variable '[bad2]' with type 'const auto &' contains multiple expressions}}
143 const auto &[bad3](); // expected-error {{expected expression}}
Richard Smith7873de02016-08-11 22:25:46 +0000144 auto &[good1] = arr;
145 auto &&[good2] = S{};
Richard Smith4b46cb92016-12-09 22:56:20 +0000146 const auto &[good3](S{});
Richard Smith7873de02016-08-11 22:25:46 +0000147 S [goodish3] = { 4 }; // expected-error {{cannot be declared with type 'S'}}
148 S [goodish4] { 4 }; // expected-error {{cannot be declared with type 'S'}}
149 }
150}