xref: /llvm-project/clang/test/CXX/drs/cwg17xx.cpp (revision 14ba3f9d07ea1664497c5d117120fb243ca221aa)
1 // RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
2 // RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
3 // RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
6 // RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
7 // RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
8 
9 namespace cwg1710 { // cwg1710: no
10 // FIXME: all of the following is well-formed
11 template <typename T> struct D1 : T::template B<int>::template C<int> {};
12 template <typename T> struct D2 : T::B<int>::template C<int> {};
13 // expected-error@-1 {{use 'template' keyword to treat 'B' as a dependent template name}}
14 template <typename T> struct D3 : T::template B<int>::C<int> {};
15 // expected-error@-1 {{use 'template' keyword to treat 'C' as a dependent template name}}
16 template <typename T> struct D4 : T::B<int>::C<int> {};
17 // expected-error@-1 {{use 'template' keyword to treat 'B' as a dependent template name}}
18 // expected-error@-2 {{use 'template' keyword to treat 'C' as a dependent template name}}
19 } // namespace cwg1710
20 
21 namespace cwg1715 { // cwg1715: 3.9
22 #if __cplusplus >= 201103L
23   struct B {
24     template<class T> B(T, typename T::Q);
25   };
26 
27   class S {
28     using Q = int;
29     template<class T> friend B::B(T, typename T::Q);
30   };
31 
32   struct D : B {
33     using B::B;
34   };
35   struct E : B { // #cwg1715-E
36     template<class T> E(T t, typename T::Q q) : B(t, q) {} // #cwg1715-E-ctor
37   };
38 
39   B b(S(), 1);
40   D d(S(), 2);
41   E e(S(), 3);
42   // since-cxx11-error@-1 {{no matching constructor for initialization of 'E'}}
43   //   since-cxx11-note@#cwg1715-E-ctor {{candidate template ignored: substitution failure [with T = S]: 'Q' is a private member of 'cwg1715::S'}}
44   //   since-cxx11-note@#cwg1715-E {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}}
45   //   since-cxx11-note@#cwg1715-E {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}}
46 #endif
47 } // namespace cwg1715
48 
49 namespace cwg1719 { // cwg1719: 19
50 #if __cplusplus >= 201103L
51 struct CStruct {
52   int one;
53   int two;
54 };
55 
56 struct CStruct2 {
57   int one;
58   int two;
59 };
60 
61 struct CStructWithQualifiers {
62   const int one;
63   volatile int two;
64 };
65 
66 static_assert(__is_layout_compatible(CStruct, const CStruct2), "");
67 static_assert(__is_layout_compatible(CStruct, volatile CStruct2), "");
68 static_assert(__is_layout_compatible(const CStruct, volatile CStruct2), "");
69 static_assert(__is_layout_compatible(int, const int), "");
70 static_assert(__is_layout_compatible(int, volatile int), "");
71 static_assert(__is_layout_compatible(const int, volatile int), "");
72 static_assert(__is_layout_compatible(CStruct, CStructWithQualifiers), "");
73 static_assert(__is_layout_compatible(int[], const volatile int[]), "");
74 #endif
75 } // namespace cwg1719
76 
77 namespace cwg1722 { // cwg1722: 9
78 #if __cplusplus >= 201103L
79 void f() {
80   const auto lambda = [](int x) { return x + 1; };
81   // Without the DR applied, this static_assert would fail.
82   static_assert(
83       noexcept((int (*)(int))(lambda)),
84       "Lambda-to-function-pointer conversion is expected to be noexcept");
85 }
86 #endif
87 } // namespace cwg1722
88 
89 namespace cwg1734 { // cwg1734: no
90 #if __cplusplus >= 201103L
91 struct A {
92     A(const A&) = delete;
93 };
94 // FIXME: 'A' should not be trivially copyable because the class lacks at least
95 // one non-deleted copy constructor, move constructor, copy assignment
96 // operator, or move assignment operator.
97 static_assert(__is_trivially_copyable(A), "");
98 #endif
99 } // namespace cwg1734
100 
101 namespace cwg1736 { // cwg1736: 3.9
102 #if __cplusplus >= 201103L
103 struct S {
104   template <class T> S(T t) {
105     struct L : S {
106       using S::S;
107     };
108     typename T::type value;
109     // since-cxx11-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}}
110     //   since-cxx11-note@#cwg1736-l {{in instantiation of function template specialization 'cwg1736::S::S<int>' requested here}}
111     //   since-cxx11-note@#cwg1736-s {{in instantiation of function template specialization 'cwg1736::S::S<cwg1736::Q>' requested here}}
112     L l(value); // #cwg1736-l
113   }
114 };
115 struct Q { typedef int type; } q;
116 S s(q); // #cwg1736-s
117 #endif
118 } // namespace cwg1736
119 
120 namespace cwg1738 { // cwg1738: sup P0136R1
121 #if __cplusplus >= 201103L
122 struct A {
123   template <typename T>
124   A(int, T) {}
125 };
126 
127 struct B : A {
128   using A::A;
129 };
130 
131 // FIXME: this is well-formed since P0136R1
132 template B::B(int, double);
133 // since-cxx11-error@-1 {{explicit instantiation of 'B' does not refer to a function template, variable template, member function, member class, or static data member}}
134 #endif
135 } // namespace cwg1738
136 
137 // cwg1748 is in cwg1748.cpp
138 
139 namespace cwg1753 { // cwg1753: 11
140   typedef int T;
141   struct A { typedef int T; };
142   namespace B { typedef int T; }
143 
144   void f(T n) {
145     n.~T();
146     n.T::~T();
147 
148     n.cwg1753::~T();
149     // expected-error@-1 {{'cwg1753' does not refer to a type name in pseudo-destructor expression; expected the name of type 'T' (aka 'int')}}
150     n.cwg1753::T::~T();
151 
152     n.A::~T();
153     // expected-error@-1 {{the type of object expression ('T' (aka 'int')) does not match the type being destroyed ('A') in pseudo-destructor expression}}
154     n.A::T::~T();
155 
156     n.B::~T();
157     // expected-error@-1 {{'B' does not refer to a type name in pseudo-destructor expression; expected the name of type 'T' (aka 'int')}}
158     n.B::T::~T();
159 
160   #if __cplusplus >= 201103L
161     n.decltype(n)::~T();
162     // since-cxx11-error@-1 {{'decltype(n)' (aka 'int') is not a class, namespace, or enumeration}}
163     n.T::~decltype(n)();
164     // since-cxx11-error@-1 {{expected a class name after '~' to name a destructor}}
165     n.~decltype(n)(); // OK
166   #endif
167   }
168 } // namespace cwg1753
169 
170 namespace cwg1756 { // cwg1756: 3.7
171 #if __cplusplus >= 201103L
172   // Direct-list-initialization of a non-class object
173 
174   int a{0};
175 
176   struct X { operator int(); } x;
177   int b{x};
178 #endif
179 } // namespace cwg1756
180 
181 namespace cwg1758 { // cwg1758: 3.7
182 #if __cplusplus >= 201103L
183   // Explicit conversion in copy/move list initialization
184 
185   struct X { X(); };
186   struct Y { explicit operator X(); } y;
187   X x{y};
188 
189   struct A {
190     A() {}
191     A(const A &) {}
192   };
193   struct B {
194     operator A() { return A(); }
195   } b;
196   A a{b};
197 #endif
198 } // namespace cwg1758
199 
200 namespace cwg1762 { // cwg1762: 14
201 #if __cplusplus >= 201103L
202   float operator ""_E(const char *);
203   float operator ""E(const char *);
204   // since-cxx11-error@-1 {{invalid suffix on literal; C++11 requires a space between literal and identifier}}
205   // since-cxx11-warning@-2 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
206 #endif
207 } // namespace cwg1762
208 
209 // cwg1772 is in cwg177x.cpp
210 
211 namespace cwg1778 { // cwg1778: 9
212   // Superseded by P1286R2.
213 #if __cplusplus >= 201103L
214   struct A { A() noexcept(true) = default; };
215   struct B { B() noexcept(false) = default; };
216   static_assert(noexcept(A()), "");
217   static_assert(!noexcept(B()), "");
218 
219   struct C { A a; C() noexcept(false) = default; };
220   struct D { B b; D() noexcept(true) = default; };
221   static_assert(!noexcept(C()), "");
222   static_assert(noexcept(D()), "");
223 #endif
224 } // namespace cwg1778
225 
226 // cwg1779 is in cwg177x.cpp
227 
228 namespace cwg1794 { // cwg1794: 2.7
229                     // NB: dup 1710
230 #if __cplusplus >= 201103L
231 template <template <typename> class Template> struct Internal {
232   template <typename Arg> using Bind = Template<Arg>;
233 };
234 
235 template <template <typename> class Template, typename Arg>
236 using Instantiate = Template<Arg>;
237 
238 template <template <typename> class Template, typename Argument>
239 using Bind = Instantiate<Internal<Template>::template Bind, Argument>;
240 #endif
241 } // namespace cwg1794
242