212 lines · cpp
1// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-unknown-linux-gnu -verify=expected,cxx17,pre2c -fcxx-exceptions2// RUN: %clang_cc1 -std=c++2b %s -triple x86_64-unknown-linux-gnu -verify=expected,cxx2b,pre2c,post2b -fcxx-exceptions3// RUN: %clang_cc1 -std=c++2c %s -triple x86_64-unknown-linux-gnu -verify=expected,cxx2c,post2b -fcxx-exceptions4// RUN: not %clang_cc1 -std=c++17 %s -triple x86_64-unknown-linux-gnu -emit-llvm-only -fcxx-exceptions5 6struct S { int a, b, c; }; // expected-note 2 {{'S::a' declared here}}7 8// A simple-declaration can be a structured binding declaration.9namespace SimpleDecl {10 auto [a_x, b_x, c_x] = S();11 12 void f(S s) {13 auto [a, b, c] = S();14 {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:; }18 }19 }20}21 22// A for-range-declaration can be a structured binding declaration.23namespace ForRangeDecl {24 extern S arr[10];25 void h() {26 for (auto [a, b, c] : arr) {27 }28 }29}30 31// Other kinds of declaration cannot.32namespace 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 1+{{'a'}}36 37 void g() {38 // A condition is allowed as a Clang extension.39 // See commentary in test/Parser/decomposed-condition.cpp40 for (; auto [a, b, c] = S(); ) {} // pre2c-warning {{structured binding declaration in a condition is a C++2c extension}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}41 if (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding declaration in a condition is a C++2c extension}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}42 if (int n; auto [a, b, c] = S()) {} // pre2c-warning {{structured binding declaration in a condition is a C++2c extension}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}43 switch (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding declaration in a condition is a C++2c extension}} expected-error {{statement requires expression of integer type ('S' invalid)}}44 switch (int n; auto [a, b, c] = S()) {} // pre2c-warning {{structured binding declaration in a condition is a C++2c extension}} expected-error {{statement requires expression of integer type ('S' invalid)}}45 while (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding declaration in a condition is a C++2c extension}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}46 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 1+{{'a'}}50 }51 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}}56 };57}58 59namespace GoodSpecifiers {60 void f() {61 int n[1];62 const volatile auto &[a] = n; // post2b-warning {{volatile qualifier in structured binding declaration is deprecated}}63 }64}65 66namespace BadSpecifiers {67 typedef int I1[1];68 I1 n;69 struct S { int n; } s;70 void f() {71 // storage-class-specifiers72 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}}77 78 // function-specifiers79 virtual auto &[e] = n; // expected-error {{not permitted in this context}}80 explicit auto &[f] = n; // expected-error {{not permitted in this context}}81 82 // misc decl-specifiers83 friend auto &[g] = n; // expected-error {{'auto' not allowed}} expected-error {{friends can only be classes or functions}}84 };85 typedef auto &[h] = n; // expected-error {{cannot be declared 'typedef'}}86 constexpr auto &[i] = n; // pre2c-error {{cannot be declared 'constexpr'}}87 }88 89 static constexpr inline thread_local auto &[j1] = n;90 // pre2c-error@-1 {{cannot be declared 'constexpr'}} \91 // expected-error@-1 {{cannot be declared 'inline'}} \92 // cxx17-warning@-1 {{declared 'static' is a C++20 extension}} \93 // cxx17-warning@-1 {{declared 'thread_local' is a C++20 extension}}94 95 static thread_local auto &[j2] = n;96 // cxx17-warning@-1 {{declared 'static' is a C++20 extension}}\97 // cxx17-warning@-1 {{declared 'thread_local' is a C++20 extension}}98 99 100 inline auto &[k] = n; // expected-error {{cannot be declared 'inline'}}101 102 const int K = 5;103 auto ([c]) = s; // expected-error {{structured binding declaration cannot be declared with parentheses}}104 void g() {105 // defining-type-specifiers other than cv-qualifiers and 'auto'106 S [a] = s; // expected-error {{cannot be declared with type 'S'}}107 decltype(auto) [b] = s; // expected-error {{cannot be declared with type 'decltype(auto)'}}108 auto ([c2]) = s; // cxx17-error {{structured binding declaration cannot be declared with parenthese}} \109 // post2b-error {{use of undeclared identifier 'c2'}} \110 // post2b-error {{expected body of lambda expression}} \111 112 // FIXME: This error is not very good.113 auto [d]() = s; // expected-error {{expected ';'}} expected-error {{expected expression}}114 auto [e][1] = s; // expected-error {{expected ';'}} expected-error {{requires an initializer}}115 116 // FIXME: This should fire the 'misplaced array declarator' diagnostic.117 int [K] arr = {0}; // expected-error {{expected ';'}} expected-error {{cannot be declared with type 'int'}} expected-error {{structured binding declaration '[K]' requires an initializer}}118 int [5] arr = {0}; // expected-error {{place the brackets after the name}}119 120 auto *[f] = s; // expected-error {{cannot be declared with type 'auto *'}} expected-error {{incompatible initializer}}121 auto S::*[g] = s; // expected-error {{cannot be declared with type 'auto S::*'}} expected-error {{incompatible initializer}}122 123 // ref-qualifiers are OK.124 auto &&[ok_1] = S();125 auto &[ok_2] = s;126 127 // attributes are OK.128 [[]] auto [ok_3] = s;129 alignas(S) auto [ok_4] = s;130 131 auto [bad_attr_2] [[]] = s; // expected-error {{expected ';'}} expected-error {{}}132 }133}134 135namespace MultiDeclarator {136 struct S { int n; };137 void f(S s) {138 auto [a] = s, [b] = s; // expected-error {{must be the only declaration}}139 auto [c] = s, d = s; // expected-error {{must be the only declaration}}140 auto e = s, [f] = s; // expected-error {{must be the only declaration}}141 auto g = s, h = s, i = s, [j] = s; // expected-error {{must be the only declaration}}142 }143}144 145namespace Template {146 int n[3];147 // Structured binding template is not allowed.148 template<typename T> auto [a, b, c] = n; // expected-error {{structured binding declaration cannot be a template}}149}150 151namespace Init {152 void f() {153 int arr[1];154 struct S { int n; };155 auto &[bad1]; // expected-error {{structured binding declaration '[bad1]' requires an initializer}}156 const auto &[bad2](S{}, S{}); // expected-error {{initializer for variable '[bad2]' with type 'const auto &' contains multiple expressions}}157 const auto &[bad3](); // expected-error {{expected expression}}158 auto &[good1] = arr;159 auto &&[good2] = S{};160 const auto &[good3](S{});161 S [goodish3] = { 4 }; // expected-error {{cannot be declared with type 'S'}}162 S [goodish4] { 4 }; // expected-error {{cannot be declared with type 'S'}}163 }164}165 166 167namespace attributes {168 169struct S{170 int a;171 int b = 0;172};173 174void err() {175 auto [[]] = S{0}; // expected-error {{expected unqualified-id}}176 auto [ alignas(42) a, foo ] = S{0}; // expected-error {{an attribute list cannot appear here}}177 auto [ c, [[]] d ] = S{0}; // expected-error {{an attribute list cannot appear here}}178 auto [ e, alignas(42) f ] = S{0}; // expected-error {{an attribute list cannot appear here}}179}180 181void ok() {182 auto [ a alignas(42) [[]], b alignas(42) [[]]] = S{0}; // expected-error 2{{'alignas' attribute only applies to variables, data members and tag types}} \183 // pre2c-warning 2{{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}184 auto [ c [[]] alignas(42), d [[]] alignas(42) [[]]] = S{0}; // expected-error 2{{'alignas' attribute only applies to variables, data members and tag types}} \185 // pre2c-warning 2{{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}186}187 188 189auto [G1 [[deprecated]], G2 [[deprecated]]] = S{42}; // #deprecated-here190// pre2c-warning@-1 2{{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}191 192int test() {193 return G1 + G2; // expected-warning {{'G1' is deprecated}} expected-note@#deprecated-here {{here}} \194 // expected-warning {{'G2' is deprecated}} expected-note@#deprecated-here {{here}}195}196 197void invalid_attributes() {198 // pre2c-warning@+1 {{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}199 auto [a alignas(42) // expected-error {{'alignas' attribute only applies to variables, data members and tag types}}200 [[assume(true), // expected-error {{'assume' attribute cannot be applied to a declaration}}201 carries_dependency, // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}202 fallthrough, // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}203 likely, // expected-error {{'likely' attribute cannot be applied to a declaration}}204 unlikely, // expected-error {{'unlikely' attribute cannot be applied to a declaration}}205 nodiscard, // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, function pointers, and typedefs}}206 noreturn, // expected-error {{'noreturn' attribute only applies to functions}}207 no_unique_address]], // expected-error {{'no_unique_address' attribute only applies to non-bit-field non-static data members}}208 b] = S{0};209}210 211}212