1 // RUN: %clang_cc1 -std=c++1z %s -verify -fcxx-exceptions 2 3 struct S { int a, b, c; }; 4 5 // A simple-declaration can be a decompsition declaration. 6 namespace 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. 20 namespace 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. 29 namespace 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 55 namespace GoodSpecifiers { 56 void f() { 57 int n[1]; 58 const volatile auto &[a] = n; 59 } 60 } 61 62 namespace 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'}} 70 extern auto &[c] = n; // expected-error {{cannot be declared 'extern'}} expected-error {{cannot have an initializer}} 71 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. 100 int [K] arr = {0}; // expected-error {{expected ';'}} expected-error {{cannot be declared with type 'int'}} expected-error {{decomposition declaration '[K]' requires an initializer}} 101 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 121 namespace 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 131 namespace 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 } 136 137 namespace Init { 138 void f() { 139 int arr[1]; 140 struct S { int n; }; 141 auto &[bad1]; // expected-error {{decomposition declaration '[bad1]' requires an initializer}} 142 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}} 144 auto &[good1] = arr; 145 auto &&[good2] = S{}; 146 const auto &[good3](S{}); 147 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 } 151