xref: /llvm-project/clang/test/CXX/drs/cwg21xx.cpp (revision 14ba3f9d07ea1664497c5d117120fb243ca221aa)
1 // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
3 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
6 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
7 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
8 
9 #if __cplusplus == 199711L
10 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
11 // cxx98-error@-1 {{variadic macros are a C99 feature}}
12 #endif
13 
14 namespace std {
15   typedef __SIZE_TYPE__ size_t;
16 
17   template<typename E> struct initializer_list {
18     const E *p; size_t n;
19     initializer_list(const E *p, size_t n);
20     initializer_list();
21   };
22 
23   struct type_info;
24 }
25 
26 namespace cwg2100 { // cwg2100: 12
27   template<const int *P, bool = true> struct X {};
28   template<typename T> struct A {
29     static const int n = 1;
30     int f() {
31       return X<&n>::n; // ok, value-dependent
32     }
33     int g() {
34       static const int n = 2; // #cwg2100-n
35       return X<&n>::n; // ok, value-dependent
36       // cxx98-14-error@-1 {{non-type template argument refers to object 'n' that does not have linkage}}
37       //   cxx98-14-note@#cwg2100-n {{non-type template argument refers to object here}}
38     }
39   };
40   template<const int *P> struct X<P> {
41 #if __cplusplus == 199711L
42     static const int n = 0;
43 #else
44     static const int n = *P;
45 #endif
46   };
47   int q = A<int>().f() + A<int>().g();
48 
49   // Corresponding constructs where the address is not taken are not
50   // value-dependent.
51   template<int N, bool = true> struct Y {};
52   template<typename T> struct B {
53     static const int n = 1;
54     int f() {
55       return Y<n>::declared_later;
56       // expected-error@-1 {{no member named 'declared_later' in 'cwg2100::Y<1>'}}
57     }
58     int g() {
59       static const int n = 2;
60       return Y<n>::declared_later;
61       // expected-error@-1 {{no member named 'declared_later' in 'cwg2100::Y<2>'}}
62     }
63   };
64   template<int N> struct Y<N> {
65     static const int declared_later = 0;
66   };
67 } // namespace cwg2100
68 
69 namespace cwg2103 { // cwg2103: 2.7
70   void f() {
71     int a;
72     int &r = a; // #cwg2103-r
73     struct Inner {
74       void f() {
75         int &s = r;
76         // expected-error@-1 {{reference to local variable 'r' declared in enclosing function 'cwg2103::f'}}
77         //   expected-note@#cwg2103-r {{'r' declared here}}
78         (void)s;
79       }
80     };
81   }
82 } // namespace cwg2103
83 
84 namespace cwg2120 { // cwg2120: 7
85   struct A {};
86   struct B : A {};
87   struct C { A a; };
88   struct D { C c[5]; };
89   struct E : B { D d; };
90   static_assert(__is_standard_layout(B), "");
91   static_assert(__is_standard_layout(D), "");
92   static_assert(!__is_standard_layout(E), "");
93 } // namespace cwg2120
94 
95 namespace cwg2126 { // cwg2126: 12
96 #if __cplusplus >= 201103L
97   struct A { int n; };
98 
99   const A &a = {1};              // const temporary
100   A &b = (A &)(const A &)A{1};   // const temporary
101   A &&c = (A &&)(const A &)A{1}; // const temporary
102 
103   A &&d = {1};                   // non-const temporary #cwg21260-d
104   const A &e = (A &)(A &&) A{1}; // non-const temporary #cwg21260-e
105   A &&f = (A &&)(A &&) A{1};     // non-const temporary #cwg21260-f
106 
107   constexpr const A &g = {1};    // const temporary
108   constexpr A &&h = {1};         // non-const temporary #cwg21260-h
109 
110   struct B { const A &a; };
111   B i = {{1}};           // extending decl not usable in constant expr #cwg21260-i
112   const B j = {{1}};     // extending decl not usable in constant expr #cwg21260-j
113   constexpr B k = {{1}}; // extending decl usable in constant expr
114 
115   static_assert(a.n == 1, "");
116   static_assert(b.n == 1, "");
117   static_assert(c.n == 1, "");
118   static_assert(d.n == 1, "");
119   // since-cxx11-error@-1 {{static assertion expression is not an integral constant expression}}
120   //   since-cxx11-note@-2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
121   //   since-cxx11-note@#cwg21260-d {{temporary created here}}
122   static_assert(e.n == 1, "");
123   // since-cxx11-error@-1 {{static assertion expression is not an integral constant expression}}
124   //   since-cxx11-note@-2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
125   //   since-cxx11-note@#cwg21260-e {{temporary created here}}
126   static_assert(f.n == 1, "");
127   // since-cxx11-error@-1 {{static assertion expression is not an integral constant expression}}
128   //   since-cxx11-note@-2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
129   //   since-cxx11-note@#cwg21260-f {{temporary created here}}
130   static_assert(g.n == 1, "");
131   static_assert(h.n == 1, "");
132   // since-cxx11-error@-1 {{static assertion expression is not an integral constant expression}}
133   //   since-cxx11-note@-2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
134   //   since-cxx11-note@#cwg21260-h {{temporary created here}}
135   static_assert(i.a.n == 1, "");
136   // since-cxx11-error@-1 {{static assertion expression is not an integral constant expression}}
137   //   since-cxx11-note@-2 {{read of non-constexpr variable 'i' is not allowed in a constant expression}}
138   //   since-cxx11-note@#cwg21260-i {{declared here}}
139   static_assert(j.a.n == 1, "");
140   // since-cxx11-error@-1 {{static assertion expression is not an integral constant expression}}
141   //   since-cxx11-note@-2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
142   //   since-cxx11-note@#cwg21260-j {{temporary created here}}
143   static_assert(k.a.n == 1, "");
144 #endif
145 } // namespace cwg2126
146 
147 namespace cwg2137 { // cwg2137: 20
148 #if __cplusplus >= 201103L
149   struct Q {
150     Q();
151     Q(Q&&);
152     Q(std::initializer_list<Q>) = delete; // #cwg2137-Qcons
153   };
154 
155   Q x = Q { Q() };
156   // since-cxx11-error@-1 {{call to deleted constructor of 'Q'}}
157   //   since-cxx11-note@#cwg2137-Qcons {{'Q' has been explicitly marked deleted here}}
158 
159   int f(Q); // #cwg2137-f
160   int y = f({ Q() });
161   // since-cxx11-error@-1 {{call to deleted constructor of 'Q'}}
162   //   since-cxx11-note@#cwg2137-Qcons {{'Q' has been explicitly marked deleted here}}
163   //   since-cxx11-note@#cwg2137-f {{passing argument to parameter here}}
164 
165   struct U {
166     U();
167     U(const U&);
168   };
169 
170   struct Derived : U {
171     Derived();
172     Derived(const Derived&);
173   } d;
174 
175   int g(Derived);
176   int g(U(&&)[1]) = delete;
177 
178   int z = g({ d });
179 #endif
180 } // namespace cwg2137
181 
182 namespace cwg2140 { // cwg2140: 9
183 #if __cplusplus >= 201103L
184   union U { int a; decltype(nullptr) b; };
185   constexpr int *test(U u) {
186     return u.b;
187   }
188   static_assert(!test({123}), "u.b should be valid even when b is inactive");
189 #endif
190 } // namespace cwg2140
191 
192 namespace cwg2141 { // cwg2141: 17
193 struct A{};
194 
195 template <typename T>
196 struct B{};
197 
198 void foo() {
199   struct A *b = (1 == 1) ? new struct A : new struct A;
200   struct S *a = (1 == 1) ? new struct S : new struct S;
201   // expected-error@-1 {{allocation of incomplete type 'struct S'}}
202   //   expected-note@-2 {{forward declaration of 'S'}}
203   // expected-error@-3 {{allocation of incomplete type 'struct S'}}
204   //   expected-note@-4 {{forward declaration of 'S'}}
205 
206 #if __cplusplus >= 201103L
207   A *aa = new struct A{};
208   B<int> *bb = new struct B<int>{};
209   (void)new struct C{};
210   // since-cxx11-error@-1 {{allocation of incomplete type 'struct C'}}
211   //   since-cxx11-note@-2 {{forward declaration of 'C'}}
212 
213   struct A *c = (1 == 1) ? new struct A {} : new struct A {};
214 
215   alignof(struct D{});
216   // since-cxx11-error@-1 {{'D' cannot be defined in a type specifier}}
217 #endif
218 
219   sizeof(struct E{});
220   // expected-error@-1 {{'E' cannot be defined in a type specifier}}
221 
222 }
223 } // namespace cwg2141
224 
225 // cwg2149 is in cwg2149.cpp
226 
227 namespace cwg2157 { // cwg2157: 11
228 #if __cplusplus >= 201103L
229   enum E : int;
230   struct X {
231     enum cwg2157::E : int();
232     // since-cxx11-error@-1 {{ISO C++ only allows ':' in member enumeration declaration to introduce a fixed underlying type, not an anonymous bit-field}}
233   };
234 #endif
235 } // namespace cwg2157
236 
237 // cwg2165: na
238 
239 namespace cwg2170 { // cwg2170: 9
240 #if __cplusplus >= 201103L
241   void f() {
242     constexpr int arr[3] = {1, 2, 3}; // #cwg2170-arr
243     struct S {
244       int get(int n) { return arr[n]; }
245       const int &get_ref(int n) { return arr[n]; }
246       // since-cxx11-warning@-1 {{reference to stack memory associated with local variable 'arr' returned}} FIXME
247       // since-cxx11-error@-2 {{reference to local variable 'arr' declared in enclosing function 'cwg2170::f'}}
248       //   since-cxx11-note@#cwg2170-arr {{'arr' declared here}}
249     };
250   }
251 #endif
252 } // namespace cwg2170
253 
254 namespace cwg2171 { // cwg2171: 15
255 #if __cplusplus >= 201103L
256 
257 struct NonConstCopy {
258   NonConstCopy(NonConstCopy &) = default;
259   NonConstCopy &operator=(NonConstCopy &) = default;
260 };
261 
262 static_assert(__is_trivially_copyable(NonConstCopy), "");
263 static_assert(__is_trivially_constructible(NonConstCopy, NonConstCopy &), "");
264 static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy), "");
265 static_assert(!__is_trivially_constructible(NonConstCopy, const NonConstCopy &), "");
266 static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy &&), "");
267 
268 static_assert(__is_trivially_assignable(NonConstCopy, NonConstCopy &), "");
269 static_assert(__is_trivially_assignable(NonConstCopy &, NonConstCopy &), "");
270 static_assert(!__is_trivially_assignable(NonConstCopy &, const NonConstCopy &), "");
271 static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy), "");
272 static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy &&), "");
273 static_assert(__is_trivially_assignable(NonConstCopy &&, NonConstCopy &), "");
274 static_assert(!__is_trivially_assignable(NonConstCopy &&, const NonConstCopy &), "");
275 static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy), "");
276 static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy &&), "");
277 
278 #endif
279 } // namespace cwg2171
280 
281 namespace cwg2191 { // cwg2191: 19
282 #if __cplusplus >= 201103L
283 struct B { virtual void f() { } };
284 struct D : B { } d;
285 static_assert(noexcept(typeid(d)), "");
286 static_assert(!noexcept(typeid(*static_cast<D*>(nullptr))), "");
287 #endif
288 } // namespace cwg2191
289 
290 namespace cwg2180 { // cwg2180: 3.0
291   class A {
292     A &operator=(const A &); // #cwg2180-A-copy
293     A &operator=(A &&); // #cwg2180-A-move
294     // cxx98-error@-1 {{rvalue references are a C++11 extension}}
295   };
296 
297   struct B : virtual A { // #cwg2180-B
298     B &operator=(const B &);
299     B &operator=(B &&);
300     // cxx98-error@-1 {{rvalue references are a C++11 extension}}
301     virtual void foo() = 0;
302   };
303   B &B::operator=(const B&) = default; // #cwg2180-B-copy
304   // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
305   // cxx98-error@-2 {{'operator=' is a private member of 'cwg2180::A'}}
306   //   cxx98-note@-3 {{in defaulted copy assignment operator for 'cwg2180::B' first required here}}
307   //   cxx98-note@#cwg2180-A-copy {{implicitly declared private here}}
308   // since-cxx11-error@#cwg2180-B-copy {{defaulting this copy assignment operator would delete it after its first declaration}}
309   //   since-cxx11-note@#cwg2180-B {{copy assignment operator of 'B' is implicitly deleted because base class 'A' has an inaccessible copy assignment operator}}
310   B &B::operator=(B&&) = default; // #cwg2180-B-move
311   // cxx98-error@-1 {{rvalue references are a C++11 extension}}
312   // cxx98-error@-2 {{defaulted function definitions are a C++11 extension}}
313   // cxx98-error@-3 {{'operator=' is a private member of 'cwg2180::A'}}
314   //   cxx98-note@-4 {{in defaulted move assignment operator for 'cwg2180::B' first required here}}
315   //   cxx98-note@#cwg2180-A-move {{implicitly declared private here}}
316   // since-cxx11-error@#cwg2180-B-move {{defaulting this move assignment operator would delete it after its first declaration}}
317   //   since-cxx11-note@#cwg2180-B {{move assignment operator of 'B' is implicitly deleted because base class 'A' has an inaccessible move assignment operator}}
318 } // namespace cwg2180
319 
320 namespace cwg2199 { // cwg2199: 3.8
321                    // NB: reusing part of cwg407 test
322 namespace A {
323   struct S {};
324 }
325 namespace B {
326   typedef int S;
327 }
328 namespace E {
329   typedef A::S S;
330   using A::S;
331   struct S s;
332 }
333 namespace F {
334   typedef A::S S;
335 }
336 namespace G {
337   using namespace A;
338   using namespace F;
339   struct S s;
340 }
341 namespace H {
342   using namespace F;
343   using namespace A;
344   struct S s;
345 }
346 } // namespace cwg2199
347