xref: /llvm-project/clang/test/CXX/drs/cwg28xx.cpp (revision eff126501efc3981727ef0e918c4dca0fa2eb778)
1 // RUN: %clang_cc1 -std=c++98 -pedantic-errors -verify=expected,cxx98 %s
2 // RUN: %clang_cc1 -std=c++11 -pedantic-errors -verify=expected,since-cxx11,cxx11-23 %s
3 // RUN: %clang_cc1 -std=c++14 -pedantic-errors -verify=expected,since-cxx11,cxx11-23 %s
4 // RUN: %clang_cc1 -std=c++17 -pedantic-errors -verify=expected,since-cxx11,cxx11-23 %s
5 // RUN: %clang_cc1 -std=c++20 -pedantic-errors -verify=expected,since-cxx11,cxx11-23,since-cxx20 %s
6 // RUN: %clang_cc1 -std=c++23 -pedantic-errors -verify=expected,since-cxx11,cxx11-23,since-cxx20,since-cxx23 %s
7 // RUN: %clang_cc1 -std=c++2c -pedantic-errors -verify=expected,since-cxx11,since-cxx20,since-cxx23,since-cxx26 %s
8 
9 
10 int main() {} // required for cwg2811
11 
12 namespace cwg2811 { // cwg2811: 3.5
13 #if __cplusplus >= 201103L
14 void f() {
15   (void)[&] {
16     using T = decltype(main);
17     // since-cxx11-error@-1 {{referring to 'main' within an expression is a Clang extension}}
18   };
19   using T2 = decltype(main);
20   // since-cxx11-error@-1 {{referring to 'main' within an expression is a Clang extension}}
21 }
22 
23 using T = decltype(main);
24 // since-cxx11-error@-1 {{referring to 'main' within an expression is a Clang extension}}
25 
26 int main();
27 
28 using U = decltype(main);
29 using U2 = decltype(&main);
30 #endif
31 } // namespace cwg2811
32 
33 namespace cwg2813 { // cwg2813: 20
34 #if __cplusplus >= 202302L
35 struct X {
36   X() = default;
37 
38   X(const X&) = delete;
39   X& operator=(const X&) = delete;
40 
41   void f(this X self) { }
42 };
43 
44 void f() {
45   X{}.f();
46 }
47 #endif
48 } // namespace cwg2813
49 
50 namespace cwg2819 { // cwg2819: 19 c++26
51 #if __cplusplus >= 201103L
52   // CWG 2024-04-19: This issue is not a DR.
53   constexpr void* p = nullptr;
54   constexpr int* q = static_cast<int*>(p); // #cwg2819-q
55   // cxx11-23-error@-1 {{constexpr variable 'q' must be initialized by a constant expression}}
56   //   cxx11-23-note@-2 {{cast from 'void *' is not allowed in a constant expression}}
57   static_assert(q == nullptr, "");
58   // cxx11-23-error@-1 {{static assertion expression is not an integral constant expression}}
59   //   cxx11-23-note@-2 {{initializer of 'q' is not a constant expression}}
60   //   cxx11-23-note@#cwg2819-q {{declared here}}
61 #endif
62 } // namespace cwg2819
63 
64 namespace cwg2847 { // cwg2847: 19 review 2024-03-01
65 
66 #if __cplusplus >= 202002L
67 
68 template<typename>
69 void i();
70 
71 struct A {
72   template<typename>
73   void f() requires true;
74 
75   template<>
76   void f<int>() requires true;
77   // since-cxx20-error@-1 {{explicit specialization cannot have a trailing requires clause unless it declares a function template}}
78 
79   friend void i<int>() requires true;
80   // since-cxx20-error@-1 {{friend specialization cannot have a trailing requires clause unless it declares a function template}}
81 };
82 
83 template<typename>
84 struct B {
85   void f() requires true;
86 
87   template<typename>
88   void g() requires true;
89 
90   template<typename>
91   void h() requires true;
92 
93   template<>
94   void h<int>() requires true;
95   // since-cxx20-error@-1 {{explicit specialization cannot have a trailing requires clause unless it declares a function template}}
96 
97   friend void i<int>() requires true;
98   // since-cxx20-error@-1 {{friend specialization cannot have a trailing requires clause unless it declares a function template}}
99 };
100 
101 template<>
102 void B<int>::f() requires true;
103 // since-cxx20-error@-1 {{explicit specialization cannot have a trailing requires clause unless it declares a function template}}
104 
105 template<>
106 template<typename T>
107 void B<int>::g() requires true;
108 
109 #endif
110 
111 } // namespace cwg2847
112 
113 namespace cwg2857 { // cwg2857: no
114 struct A {};
115 template <typename>
116 struct D;
117 namespace N {
118   struct B {};
119   void adl_only(A*, D<int>*); // #cwg2857-adl_only
120 }
121 
122 void f(A* a, D<int>* d) {
123   adl_only(a, d);
124   // expected-error@-1 {{use of undeclared identifier 'adl_only'; did you mean 'N::adl_only'?}}
125   //   expected-note@#cwg2857-adl_only {{'N::adl_only' declared here}}
126 }
127 
128 #if __cplusplus >= 201103L
129 template <typename>
130 struct D : N::B {
131   // FIXME: ADL shouldn't associate it's base B and N since D is not complete here
132   decltype(adl_only((A*) nullptr, (D*) nullptr)) f;
133 };
134 #endif
135 } // namespace cwg2857
136 
137 namespace cwg2858 { // cwg2858: 19
138 
139 #if __cplusplus > 202302L
140 
141 template<typename... Ts>
142 struct A {
143   // FIXME: The nested-name-specifier in the following friend declarations are declarative,
144   // but we don't treat them as such (yet).
145   friend void Ts...[0]::f();
146   template<typename U>
147   friend void Ts...[0]::g();
148 
149   friend struct Ts...[0]::B;
150   // FIXME: The index of the pack-index-specifier is printed as a memory address in the diagnostic.
151   template<typename U>
152   friend struct Ts...[0]::C;
153   // since-cxx26-warning@-1 {{dependent nested name specifier 'Ts...[0]::' for friend template declaration is not supported; ignoring this friend declaration}}
154 };
155 
156 #endif
157 
158 } // namespace cwg2858
159 
160 namespace cwg2877 { // cwg2877: 19
161 #if __cplusplus >= 202002L
162 enum E { x };
163 void f() {
164   int E;
165   using enum E;   // OK
166 }
167 using F = E;
168 using enum F;     // OK
169 template<class T> using EE = T;
170 void g() {
171   using enum EE<E>;  // OK
172 }
173 #endif
174 } // namespace cwg2877
175 
176 namespace cwg2881 { // cwg2881: 19
177 #if __cplusplus >= 202302L
178 template <typename T> struct A : T {};
179 template <typename T> struct B : T {};
180 template <typename T> struct C : virtual T { C(T t) : T(t) {} };
181 template <typename T> struct D : virtual T { D(T t) : T(t) {} };
182 
183 template <typename Ts>
184 struct O1 : A<Ts>, B<Ts> {
185   using A<Ts>::operator();
186   using B<Ts>::operator();
187 };
188 
189 template <typename Ts> struct O2 : protected Ts { // #cwg2881-O2
190   using Ts::operator();
191   O2(Ts ts) : Ts(ts) {}
192 };
193 
194 template <typename Ts> struct O3 : private Ts { // #cwg2881-O3
195   using Ts::operator();
196   O3(Ts ts) : Ts(ts) {}
197 };
198 
199 // Not ambiguous because of virtual inheritance.
200 template <typename Ts>
201 struct O4 : C<Ts>, D<Ts> {
202   using C<Ts>::operator();
203   using D<Ts>::operator();
204   O4(Ts t) : Ts(t), C<Ts>(t), D<Ts>(t) {}
205 };
206 
207 // This still has a public path to the lambda, and it's also not
208 // ambiguous because of virtual inheritance.
209 template <typename Ts>
210 struct O5 : private C<Ts>, D<Ts> {
211   using C<Ts>::operator();
212   using D<Ts>::operator();
213   O5(Ts t) : Ts(t), C<Ts>(t), D<Ts>(t) {}
214 };
215 
216 // This is only invalid if we call T's call operator.
217 template <typename T, typename U>
218 struct O6 : private T, U { // #cwg2881-O6
219   using T::operator();
220   using U::operator();
221   O6(T t, U u) : T(t), U(u) {}
222 };
223 
224 void f() {
225   int x;
226   auto L1 = [=](this auto&& self) { (void) &x; };
227   auto L2 = [&](this auto&& self) { (void) &x; };
228   O1<decltype(L1)>{L1, L1}();
229   /* since-cxx23-error-re@-1 {{inaccessible due to ambiguity:
230     struct cwg2881::O1<class (lambda at {{.+}})> -> A<(lambda at {{.+}})> -> class (lambda at {{.+}})
231     struct cwg2881::O1<class (lambda at {{.+}})> -> B<(lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
232   O1<decltype(L2)>{L2, L2}();
233   /* since-cxx23-error-re@-1 {{inaccessible due to ambiguity:
234     struct cwg2881::O1<class (lambda at {{.+}})> -> A<(lambda at {{.+}})> -> class (lambda at {{.+}})
235     struct cwg2881::O1<class (lambda at {{.+}})> -> B<(lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
236   O2{L1}();
237   // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O2<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}}
238   //   since-cxx23-note@#cwg2881-O2 {{declared protected here}}
239   O3{L1}();
240   // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O3<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}}
241   //   since-cxx23-note@#cwg2881-O3 {{declared private here}}
242   O4{L1}();
243   O5{L1}();
244   O6 o{L1, L2};
245   o.decltype(L1)::operator()();
246   // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O6<(lambda at {{.+}}), (lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}}
247   //   since-cxx23-note@#cwg2881-O6 {{declared private here}}
248   o.decltype(L1)::operator()(); // No error here because we've already diagnosed this method.
249   o.decltype(L2)::operator()();
250 }
251 
252 void f2() {
253   int x = 0;
254   auto lambda = [x] (this auto self) { return x; };
255   using Lambda = decltype(lambda);
256   struct D : private Lambda { // #cwg2881-D
257     D(Lambda l) : Lambda(l) {}
258     using Lambda::operator();
259     friend Lambda;
260   } d(lambda);
261   d();
262   // since-cxx23-error@-1 {{invalid explicit object parameter type 'D' in lambda with capture; the type must derive publicly from the lambda}}
263   //   since-cxx23-note@#cwg2881-D {{declared private here}}
264 }
265 
266 template <typename L>
267 struct Private : private L {
268   using L::operator();
269   Private(L l) : L(l) {}
270 };
271 
272 template<typename T>
273 struct Indirect : T {
274   using T::operator();
275 };
276 
277 template<typename T>
278 struct Ambiguous : Indirect<T>, T {
279 /* since-cxx23-warning-re@-1 {{direct base '(lambda at {{.+}})' is inaccessible due to ambiguity:
280     struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<(lambda at {{.+}})> -> class (lambda at {{.+}})
281     struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
282 //   since-cxx23-note-re@#cwg2881-f4 {{in instantiation of template class 'cwg2881::Ambiguous<(lambda at {{.+}})>' requested here}}
283 //   since-cxx34-note-re@#cwg2881-f4-call {{while substituting deduced template arguments into function template 'f4' [with L = (lambda at {{.+}})]}}
284   using Indirect<T>::operator();
285 };
286 
287 template <typename L>
288 constexpr auto f3(L l) -> decltype(Private<L>{l}()) { return l(); } // #cwg2881-f3
289 
290 template <typename L>
291 constexpr auto f4(L l) -> decltype(Ambiguous<L>{{l}, l}()) { return l(); } // #cwg2881-f4
292 
293 template<typename T>
294 concept is_callable = requires(T t) { { t() }; };
295 
296 void g() {
297   int x = 0;
298   auto lambda = [x](this auto self) {};
299   f3(lambda);
300   // since-cxx23-error@-1 {{no matching function for call to 'f3'}}
301   //   since-cxx23-note-re@#cwg2881-f3 {{candidate template ignored: substitution failure [with L = (lambda at {{.+}})]: invalid explicit object parameter type 'cwg2881::Private<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}}
302   f4(lambda); // #cwg2881-f4-call
303   // expected-error@-1 {{no matching function for call to 'f4'}}
304   //   expected-note-re@-2 {{while substituting deduced template arguments into function template 'f4' [with L = (lambda at {{.+}})]}}
305   /*   expected-note-re@#cwg2881-f4 {{candidate template ignored: substitution failure [with L = (lambda at {{.+}})]: lambda '(lambda at {{.+}})' is inaccessible due to ambiguity:
306     struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<(lambda at {{.+}})> -> class (lambda at {{.+}})
307     struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
308   static_assert(!is_callable<Private<decltype(lambda)>>);
309   static_assert(!is_callable<Ambiguous<decltype(lambda)>>);
310 }
311 #endif
312 } // namespace cwg2881
313 
314 namespace cwg2882 { // cwg2882: 2.7
315 struct C {
316   operator void() = delete;
317   // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 'void' will never be used}}
318   // cxx98-error@-2 {{deleted function definitions are a C++11 extension}}
319 };
320 
321 void f(C c) {
322   (void)c;
323 }
324 } // namespace cwg2882
325 
326 namespace cwg2883 { // cwg2883: no
327 #if __cplusplus >= 201103L
328 void f() {
329   int x;
330   (void)[&] {
331     return x;
332   };
333 }
334 #endif
335 #if __cplusplus >= 202002L
336 struct A {
337   A() = default;
338   A(const A &) = delete; // #cwg2883-A-copy-ctor
339   constexpr operator int() { return 42; }
340 };
341 void g() {
342   constexpr A a;
343   // FIXME: OK, not odr-usable from a default template argument, and not odr-used
344   (void)[=]<typename T, int = a> {};
345   // since-cxx20-error@-1 {{call to deleted constructor of 'const A'}}
346   //   since-cxx20-note@#cwg2883-A-copy-ctor {{'A' has been explicitly marked deleted here}}
347 }
348 #endif
349 } // namespace cwg2883
350 
351 namespace cwg2885 { // cwg2885: 16 review 2024-05-31
352 #if __cplusplus >= 202002L
353 template <class T>
354 struct A {
355   A() requires (false) = default;
356   A() : t(42) {}
357   T t;
358 };
359 
360 struct B : A<int> {};
361 static_assert(!__is_trivially_constructible(B));
362 #endif
363 } // namespace cwg2885
364 
365 namespace cwg2886 { // cwg2886: 9
366 #if __cplusplus >= 201103L
367 struct C {
368   C() = default;
369   ~C() noexcept(false) = default;
370 };
371 
372 static_assert(noexcept(C()), "");
373 #endif
374 } // namespace cwg2886
375