llvm-project

Форк
0
/
cxx1z-decomposition.cpp 
203 строки · 10.2 Кб
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
5

6
struct S { int a, b, c; };
7

8
// A simple-declaration can be a decompsition declaration.
9
namespace 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 decomposition declaration.
23
namespace 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.
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'}}
36

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'}}
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 {{'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

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}}
63
  }
64
}
65

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}}
77

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}}
81

82
      // misc decl-specifiers
83
      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; // expected-error {{cannot be declared 'constexpr'}}
87
  }
88

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}}
91

92
  inline auto &[k] = n; // expected-error {{cannot be declared 'inline'}}
93

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}} \
103

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}}
107

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}}
111

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}}
114

115
    // ref-qualifiers are OK.
116
    auto &&[ok_1] = S();
117
    auto &[ok_2] = s;
118

119
    // attributes are OK.
120
    [[]] auto [ok_3] = s;
121
    alignas(S) auto [ok_4] = s;
122

123
    auto [bad_attr_2] [[]] = s; // expected-error {{expected ';'}} expected-error {{}}
124
  }
125
}
126

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}}
134
  }
135
}
136

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}}
141
}
142

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'}}
155
  }
156
}
157

158

159
namespace attributes {
160

161
struct S{
162
    int a;
163
    int b = 0;
164
};
165

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}}
171
}
172

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}}
178
}
179

180

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}}
183

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}}
187
}
188

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};
201
}
202

203
}
204

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.