xref: /llvm-project/clang/test/CXX/drs/cwg18xx.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,cxx11-20,cxx98-14,cxx11-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
3 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-20,since-cxx14,cxx98-14,cxx11-17,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-20,since-cxx14,since-cxx17,cxx11-17,since-cxx11,since-cxx14,cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-20,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
6 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx23,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
7 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx23,since-cxx11,since-cxx14 -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 cwg1800 { // cwg1800: 2.9
15 struct A { union { int n; }; };
16 static_assert(__is_same(__decltype(&A::n), int A::*), "");
17 } // namespace cwg1800
18 
19 namespace cwg1801 { // cwg1801: 2.8
20 static union {
21   int i;
22 };
23 
24 template <int &> struct S {}; // #cwg1801-S
25 S<i> V; // #cwg1801-S-i
26 // cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}}
27 //   cxx98-14-note@#cwg1801-S {{template parameter is declared here}}
28 // cxx17-error@#cwg1801-S-i {{non-type template argument refers to subobject '.i'}}
29 } // namespace cwg1801
30 
31 namespace cwg1802 { // cwg1802: 3.1
32 #if __cplusplus >= 201103L
33 // Using a Wikipedia example of surrogate pair:
34 // https://en.wikipedia.org/wiki/UTF-16#Examples
35 constexpr char16_t a[3] = u"\U00010437";
36 static_assert(a[0] == 0xD801, "");
37 static_assert(a[1] == 0xDC37, "");
38 static_assert(a[2] == 0x0, "");
39 #endif
40 } // namespace cwg1802
41 
42 namespace cwg1803 { // cwg1803: 2.9
43 #if __cplusplus >= 201103L
44 struct A {
45   enum E : int;
46   enum E : int {};
47   enum class EC;
48   enum class EC {};
49   enum struct ES;
50   enum struct ES {};
51 };
52 #endif
53 } // namespace cwg1803
54 
55 namespace cwg1804 { // cwg1804: 2.7
56 template <typename, typename>
57 struct A {
58   void f1();
59 
60   template <typename V>
61   void f2(V);
62 
63   class B {
64     void f3();
65   };
66 
67   template <typename>
68   class C {
69     void f4();
70   };
71 };
72 
73 template <typename U>
74 struct A<int, U> {
75   void f1();
76 
77   template <typename V>
78   void f2(V);
79 
80   class B {
81     void f3();
82   };
83 
84   template <typename>
85   class C {
86     void f4();
87   };
88 };
89 
90 class D {
91   int i;
92 
93   template <typename, typename>
94   friend struct A;
95 };
96 
97 template <typename U>
98 struct A<double, U> {
99   void f1();
100 
101   template <typename V>
102   void f2(V);
103 
104   class B {
105     void f3();
106   };
107 
108   template <typename>
109   class C {
110     void f4();
111   };
112 };
113 
114 template <typename U>
115 void A<int, U>::f1() {
116   D d;
117   d.i = 0;
118 }
119 
120 template <typename U>
121 void A<double, U>::f1() {
122   D d;
123   d.i = 0;
124 }
125 
126 template <typename U>
127 template <typename V>
128 void A<int, U>::f2(V) {
129   D d;
130   d.i = 0;
131 }
132 
133 template <typename U>
134 template <typename V>
135 void A<double, U>::f2(V) {
136   D d;
137   d.i = 0;
138 }
139 
140 template <typename U>
141 void A<int, U>::B::f3() {
142   D d;
143   d.i = 0;
144 }
145 
146 template <typename U>
147 void A<double, U>::B::f3() {
148   D d;
149   d.i = 0;
150 }
151 
152 template <typename U>
153 template <typename V>
154 void A<int, U>::C<V>::f4() {
155   D d;
156   d.i = 0;
157 }
158 
159 template <typename U>
160 template <typename V>
161 void A<double, U>::C<V>::f4() {
162   D d;
163   d.i = 0;
164 }
165 } // namespace cwg1804
166 
167 // cwg1807 is in cwg1807.cpp
168 
169 namespace cwg1812 { // cwg1812: no
170                    // NB: dup 1710
171 #if __cplusplus >= 201103L
172 template <typename T> struct A {
173   using B = typename T::C<int>;
174   // since-cxx11-error@-1 {{use 'template' keyword to treat 'C' as a dependent template name}}
175 };
176 #endif
177 } // namespace cwg1812
178 
179 namespace cwg1813 { // cwg1813: 7
180   struct B { int i; };
181   struct C : B {};
182   struct D : C {};
183   struct E : D { char : 4; };
184 
185   static_assert(__is_standard_layout(B), "");
186   static_assert(__is_standard_layout(C), "");
187   static_assert(__is_standard_layout(D), "");
188   static_assert(!__is_standard_layout(E), "");
189 
190   struct Q {};
191   struct S : Q {};
192   struct T : Q {};
193   struct U : S, T {};
194 
195   static_assert(__is_standard_layout(Q), "");
196   static_assert(__is_standard_layout(S), "");
197   static_assert(__is_standard_layout(T), "");
198   static_assert(!__is_standard_layout(U), "");
199 }
200 
201 namespace cwg1814 { // cwg1814: 3.1
202 #if __cplusplus >= 201103L
203   void test() {
204     auto lam = [](int x = 42) { return x; };
205   }
206 #endif
207 } // namespace cwg1814
208 
209 namespace cwg1815 { // cwg1815: 20
210 #if __cplusplus >= 201402L
211   struct A { int &&r = 0; };
212   A a = {};
213 
214   struct B { int &&r = 0; }; // #cwg1815-B
215   // since-cxx14-error@-1 {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
216   //   since-cxx14-note@#cwg1815-B {{initializing field 'r' with default member initializer}}
217   //   since-cxx14-note@#cwg1815-b {{in implicit default constructor for 'cwg1815::B' first required here}}
218   B b; // #cwg1815-b
219 
220 #if __cplusplus >= 201703L
221   struct C { const int &r = 0; };
222   constexpr C c = {}; // OK, since cwg1815
223   static_assert(c.r == 0);
224 
225   constexpr int f() {
226     A a = {}; // OK, since cwg1815
227     return a.r;
228   }
229   static_assert(f() == 0);
230 #endif
231 #endif
232 } // namespace cwg1815
233 
234 // cwg1818 is in cwg1818.cpp
235 
236 namespace cwg1820 { // cwg1820: 3.5
237 typedef int A;
238 typedef int cwg1820::A;
239 // expected-warning@-1 {{extra qualification on member 'A'}}
240 // expected-error@-2 {{typedef declarator cannot be qualified}}
241 
242 namespace B {
243 typedef int cwg1820::A;
244 // expected-error@-1 {{cannot define or redeclare 'A' here because namespace 'B' does not enclose namespace 'cwg1820'}}
245 // expected-error@-2 {{typedef declarator cannot be qualified}}
246 }
247 
248 class C1 {
249   typedef int cwg1820::A;
250   // expected-error@-1 {{non-friend class member 'A' cannot have a qualified name}}
251   // expected-error@-2 {{typedef declarator cannot be qualified}}
252 };
253 
254 template <typename>
255 class C2 {
256   typedef int cwg1820::A;
257   // expected-error@-1 {{non-friend class member 'A' cannot have a qualified name}}
258   // expected-error@-2 {{typedef declarator cannot be qualified}}
259 };
260 
261 void d1() {
262   typedef int cwg1820::A;
263   // expected-error@-1 {{definition or redeclaration of 'A' not allowed inside a function}}
264   // expected-error@-2 {{typedef declarator cannot be qualified}}
265 }
266 
267 template<typename>
268 void d2() {
269   typedef int cwg1820::A;
270   // expected-error@-1 {{definition or redeclaration of 'A' not allowed inside a function}}
271   // expected-error@-2 {{typedef declarator cannot be qualified}}
272 }
273 
274 #if __cplusplus >= 201103L
275 auto e = [] {
276   typedef int cwg1820::A;
277   // since-cxx11-error@-1 {{definition or redeclaration of 'A' not allowed inside a function}}
278   // since-cxx11-error@-2 {{typedef declarator cannot be qualified}}
279 };
280 #endif
281 } // namespace cwg1820
282 
283 namespace cwg1821 { // cwg1821: 2.9
284 struct A {
285   template <typename> struct B {
286     void f();
287   };
288   template <typename T> void B<T>::f(){};
289   // expected-error@-1 {{non-friend class member 'f' cannot have a qualified name}}
290 
291   struct C {
292     void f();
293   };
294   void C::f() {}
295   // expected-error@-1 {{non-friend class member 'f' cannot have a qualified name}}
296 };
297 } // namespace cwg1821
298 
299 namespace cwg1822 { // cwg1822: 3.1
300 #if __cplusplus >= 201103L
301   double a;
302   auto x = [] (int a) {
303     static_assert(__is_same(decltype(a), int), "should be resolved to lambda parameter");
304   };
305 #endif
306 } // namespace cwg1822
307 
308 namespace cwg1824 { // cwg1824: 2.7
309 template<typename T>
310 struct A {
311   T t;
312 };
313 
314 struct S {
315   A<S> f() { return A<S>(); }
316 };
317 } // namespace cwg1824
318 
319 namespace cwg1832 { // cwg1832: 3.0
320 enum E { // #cwg1832-E
321   a = static_cast<int>(static_cast<E>(0))
322   // expected-error@-1 {{'E' is an incomplete type}}
323   //   expected-note@#cwg1832-E {{definition of 'cwg1832::E' is not complete until the closing '}'}}
324 };
325 
326 #if __cplusplus >= 201103L
327 enum E2: decltype(static_cast<E2>(0), 0) {};
328 // since-cxx11-error@-1 {{unknown type name 'E2'}}
329 enum class E3: decltype(static_cast<E3>(0), 0) {};
330 // since-cxx11-error@-1 {{unknown type name 'E3'}}
331 #endif
332 } // namespace cwg1832
333 
334 namespace cwg1837 { // cwg1837: 3.3
335 #if __cplusplus >= 201103L
336   template <typename T>
337   struct Fish { static const bool value = true; };
338 
339   struct Other {
340     int p();
341     auto q() -> decltype(p()) *;
342   };
343 
344   class Outer {
345     friend auto Other::q() -> decltype(this->p()) *;
346     // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
347     int g();
348     int f() {
349       extern void f(decltype(this->g()) *);
350       struct Inner {
351         static_assert(Fish<decltype(this->g())>::value, "");
352         // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
353         enum { X = Fish<decltype(this->f())>::value };
354         // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
355         struct Inner2 : Fish<decltype(this->g())> { };
356         // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
357         friend void f(decltype(this->g()) *);
358         // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
359         friend auto Other::q() -> decltype(this->p()) *;
360         // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
361       };
362       return 0;
363     }
364   };
365 
366   struct A {
367     int f();
368     bool b = [] {
369       // since-cxx11-warning@-1 {{address of lambda function pointer conversion operator will always evaluate to 'true'}}
370       struct Local {
371         static_assert(sizeof(this->f()) == sizeof(int), "");
372       };
373     };
374   };
375 #endif
376 } // namespace cwg1837
377 
378 namespace cwg1862 { // cwg1862: no
379 template<class T>
380 struct A {
381   struct B {
382     void e();
383   };
384 
385   void f();
386 
387   struct D {
388     void g();
389   };
390 
391   T h();
392 
393   template<T U>
394   T i();
395 };
396 
397 template<>
398 struct A<int> {
399   struct B {
400     void e();
401   };
402 
403   int f();
404 
405   struct D {
406     void g();
407   };
408 
409   template<int U>
410   int i();
411 };
412 
413 template<>
414 struct A<float*> {
415   int* h();
416 };
417 
418 class C {
419   int private_int;
420 
421   template<class T>
422   friend struct A<T>::B;
423   // expected-warning@-1 {{dependent nested name specifier 'A<T>::' for friend class declaration is not supported; turning off access control for 'C'}}
424 
425   template<class T>
426   friend void A<T>::f();
427   // expected-warning@-1 {{dependent nested name specifier 'A<T>::' for friend class declaration is not supported; turning off access control for 'C'}}
428 
429   // FIXME: this is ill-formed, because A<T>​::​D does not end with a simple-template-id
430   template<class T>
431   friend void A<T>::D::g();
432   // expected-warning@-1 {{dependent nested name specifier 'A<T>::D::' for friend class declaration is not supported; turning off access control for 'C'}}
433 
434   template<class T>
435   friend int *A<T*>::h();
436   // expected-warning@-1 {{dependent nested name specifier 'A<T *>::' for friend class declaration is not supported; turning off access control for 'C'}}
437 
438   template<class T>
439   template<T U>
440   friend T A<T>::i();
441   // expected-warning@-1 {{dependent nested name specifier 'A<T>::' for friend class declaration is not supported; turning off access control for 'C'}}
442 };
443 
444 C c;
445 
446 template<class T>
447 void A<T>::B::e() { (void)c.private_int; }
448 void A<int>::B::e() { (void)c.private_int; }
449 
450 template<class T>
451 void A<T>::f() { (void)c.private_int; }
452 int A<int>::f() { (void)c.private_int; return 0; }
453 
454 // FIXME: both definition of 'D::g' are not friends, so they don't have access to 'private_int'
455 template<class T>
456 void A<T>::D::g() { (void)c.private_int; }
457 void A<int>::D::g() { (void)c.private_int; }
458 
459 template<class T>
460 T A<T>::h() { (void)c.private_int; }
461 int* A<float*>::h() { (void)c.private_int; return 0; }
462 
463 template<class T>
464 template<T U>
465 T A<T>::i() { (void)c.private_int; }
466 template<int U>
467 int A<int>::i() { (void)c.private_int; }
468 } // namespace cwg1862
469 
470 namespace cwg1872 { // cwg1872: 9
471 #if __cplusplus >= 201103L
472   template<typename T> struct A : T {
473     constexpr int f() const { return 0; }
474   };
475   struct X {};
476   struct Y { virtual int f() const; };
477   struct Z : virtual X {};
478 
479   constexpr int x = A<X>().f();
480   constexpr int y = A<Y>().f();
481   // cxx11-17-error@-1 {{constexpr variable 'y' must be initialized by a constant expression}}
482   //   cxx11-17-note@-2 {{cannot evaluate call to virtual function in a constant expression in C++ standards before C++20}}
483 #if __cplusplus >= 202002L
484   static_assert(y == 0);
485 #endif
486   // Note, this is invalid even though it would not use virtual dispatch.
487   constexpr int y2 = A<Y>().A<Y>::f();
488   // cxx11-17-error@-1 {{constexpr variable 'y2' must be initialized by a constant expression}}
489   //   cxx11-17-note@-2 {{cannot evaluate call to virtual function in a constant expression in C++ standards before C++20}}
490 #if __cplusplus >= 202002L
491   static_assert(y2 == 0);
492 #endif
493   constexpr int z = A<Z>().f();
494   // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a constant expression}}
495   //   cxx11-20-note@-2 {{non-literal type 'A<Z>' cannot be used in a constant expression}}
496   //   since-cxx23-note@-3 {{cannot construct object of type 'A<cwg1872::Z>' with virtual base class in a constant expression}}
497 #endif
498 } // namespace cwg1872
499 
500 namespace cwg1878 { // cwg1878: 18
501 #if __cplusplus >= 201402L
502 #if __cplusplus >= 202002L
503 template <typename T>
504 concept C = true;
505 #endif
506 
507 struct S {
508   template <typename T>
509   operator auto() const { return short(); }
510   // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}}
511   template <typename T>
512   operator const auto() const { return int(); }
513   // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}}
514   template <typename T>
515   operator const auto&() const { return char(); }
516   // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}}
517   template <typename T>
518   operator const auto*() const { return long(); }
519   // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}}
520   template <typename T>
521   operator decltype(auto)() const { return unsigned(); }
522   // since-cxx14-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}}
523 #if __cplusplus >= 202002L
524   template <typename T>
525   operator C auto() const { return float(); }
526   // since-cxx20-error@-1 {{'auto' not allowed in declaration of conversion function template}}
527   template <typename T>
528   operator C decltype(auto)() const { return double(); }
529   // since-cxx20-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}}
530 #endif
531 };
532 #endif
533 } // namespace cwg1878
534 
535 namespace cwg1881 { // cwg1881: 7
536   struct A { int a : 4; };
537   struct B : A { int b : 3; };
538   static_assert(__is_standard_layout(A), "");
539   static_assert(!__is_standard_layout(B), "");
540 
541   struct C { int : 0; };
542   struct D : C { int : 0; };
543   static_assert(__is_standard_layout(C), "");
544   static_assert(!__is_standard_layout(D), "");
545 } // namespace cwg1881
546 
547 // cwg1884 is in cwg1884.cpp
548 
549 namespace cwg1890 { // cwg1890: no drafting 2018-06-04
550 // FIXME: current consensus for CWG2335 is that the examples are well-formed.
551 namespace ex1 {
552 #if __cplusplus >= 201402L
553 struct A {
554   struct B {
555     auto foo() { return 0; } // #cwg1890-foo
556   };
557   decltype(B().foo()) x;
558   // since-cxx14-error@-1 {{function 'foo' with deduced return type cannot be used before it is defined}}
559   //   since-cxx14-note@#cwg1890-foo {{'foo' declared here}}
560 };
561 #endif
562 } // namespace ex1
563 
564 namespace ex2 {
565 #if __cplusplus >= 201103L
566 struct Bar {
567   struct Baz {
568     int a = 0;
569   };
570   static_assert(__is_constructible(Baz), "");
571   // since-cxx11-error@-1 {{static assertion failed due to requirement '__is_constructible(cwg1890::ex2::Bar::Baz)'}}
572 };
573 #endif
574 } // namespace ex2
575 } // namespace cwg1890
576 
577 void cwg1891() { // cwg1891: 4
578 #if __cplusplus >= 201103L
579   int n;
580   auto a = []{}; // #cwg1891-a
581   auto b = [=]{ return n; }; // #cwg1891-b
582   typedef decltype(a) A;
583   typedef decltype(b) B;
584 
585   static_assert(!__is_trivially_constructible(A), "");
586   // since-cxx20-error@-1 {{failed}}
587   static_assert(!__is_trivially_constructible(B), "");
588 
589   // C++20 allows default construction for non-capturing lambdas (P0624R2).
590   A x;
591   // cxx11-17-error@-1 {{no matching constructor for initialization of 'A' (aka '(lambda at}}
592   //   cxx11-17-note@#cwg1891-a {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
593   //   cxx11-17-note@#cwg1891-a {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
594   B y;
595   // since-cxx11-error@-1 {{no matching constructor for initialization of 'B' (aka '(lambda at}}
596   //   since-cxx11-note@#cwg1891-b {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
597   //   since-cxx11-note@#cwg1891-b {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
598 
599   // C++20 allows assignment for non-capturing lambdas (P0624R2).
600   a = a;
601   // cxx11-17-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
602   //   cxx11-17-note@#cwg1891-a {{lambda expression begins here}}
603   a = static_cast<A&&>(a);
604   // cxx11-17-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
605   //   cxx11-17-note@#cwg1891-a {{lambda expression begins here}}
606   b = b;
607   // since-cxx11-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
608   //   since-cxx11-note@#cwg1891-b {{lambda expression begins here}}
609   b = static_cast<B&&>(b);
610   // since-cxx11-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
611   //   since-cxx11-note@#cwg1891-b {{lambda expression begins here}}
612 #endif
613 } // void cwg1891()
614 
615 namespace cwg1894 { // cwg1894: 3.8
616                    // NB: reusing part of cwg407 test
617 namespace A {
618   struct S {};
619 }
620 namespace B {
621   typedef int S;
622 }
623 namespace E {
624   typedef A::S S;
625   using A::S;
626   struct S s;
627 }
628 namespace F {
629   typedef A::S S;
630 }
631 namespace G {
632   using namespace A;
633   using namespace F;
634   struct S s;
635 }
636 namespace H {
637   using namespace F;
638   using namespace A;
639   struct S s;
640 }
641 } // namespace cwg1894
642 
643 namespace cwg1898 { // cwg1898: 2.7
644 void e(int) {} // #cwg1898-e
645 void e(int) {}
646 // expected-error@-1 {{redefinition of 'e'}}
647 //   expected-note@#cwg1898-e {{previous definition is here}}
648 
649 void e2(int) {}
650 void e2(long) {} // OK, different type
651 
652 void f(int) {} // #cwg1898-f
653 void f(const int) {}
654 // expected-error@-1 {{redefinition of 'f'}}
655 //   expected-note@#cwg1898-f {{previous definition is here}}
656 
657 void g(int) {} // #cwg1898-g
658 void g(volatile int) {}
659 // since-cxx20-warning@-1 {{volatile-qualified parameter type 'volatile int' is deprecated}}
660 // expected-error@-2 {{redefinition of 'g'}}
661 //   expected-note@#cwg1898-g {{previous definition is here}}
662 
663 void h(int *) {} // #cwg1898-h
664 void h(int[]) {}
665 // expected-error@-1 {{redefinition of 'h'}}
666 //   expected-note@#cwg1898-h {{previous definition is here}}
667 
668 void h2(int *) {} // #cwg1898-h2
669 void h2(int[2]) {}
670 // expected-error@-1 {{redefinition of 'h2'}}
671 //   expected-note@#cwg1898-h2 {{previous definition is here}}
672 
673 void h3(int (*)[2]) {} // #cwg1898-h3
674 void h3(int [3][2]) {}
675 // expected-error@-1 {{redefinition of 'h3'}}
676 //   expected-note@#cwg1898-h3 {{previous definition is here}}
677 
678 void h4(int (*)[2]) {}
679 void h4(int [3][3]) {} // OK, differ in non-top-level extent of array
680 
681 void i(int *) {}
682 void i(const int *) {} // OK, pointee cv-qualification is not discarded
683 
684 void i2(int *) {} // #cwg1898-i2
685 void i2(int * const) {}
686 // expected-error@-1 {{redefinition of 'i2'}}
687 //   expected-note@#cwg1898-i2 {{previous definition is here}}
688 
689 void j(void(*)()) {} // #cwg1898-j
690 void j(void()) {}
691 // expected-error@-1 {{redefinition of 'j'}}
692 //   expected-note@#cwg1898-j {{previous definition is here}}
693 
694 void j2(void(int)) {} // #cwg1898-j2
695 void j2(void(const int)) {}
696 // expected-error@-1 {{redefinition of 'j2'}}
697 //   expected-note@#cwg1898-j2 {{previous definition is here}}
698 
699 struct A {
700   void k(int) {} // #cwg1898-k
701   void k(int) {}
702   // expected-error@-1 {{class member cannot be redeclared}}
703   //   expected-note@#cwg1898-k {{previous definition is here}}
704 };
705 
706 struct B : A {
707   void k(int) {} // OK, shadows A::k
708 };
709 
710 void l() {}
711 void l(...) {}
712 
713 #if __cplusplus >= 201103L
714 template <typename T>
715 void m(T) {}
716 template <typename... Ts>
717 void m(Ts...) {}
718 
719 template <typename T, typename U>
720 void m2(T, U) {}
721 template <typename... Ts, typename U>
722 void m2(Ts..., U) {}
723 #endif
724 } // namespace cwg1898
725