xref: /llvm-project/clang/test/CXX/drs/cwg19xx.cpp (revision 14ba3f9d07ea1664497c5d117120fb243ca221aa)
1 // RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-11,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
2 // RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
3 // RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
6 // RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
7 // RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
8 
9 namespace std {
10 struct type_info;
11 } // namespace std
12 
13 namespace cwg1900 { // cwg1900: 2.7
14 // See the test for CWG1477 for detailed analysis
15 namespace N {
16 struct A {
17   friend int f();
18 };
19 }
20 int N::f() { return 0; }
21 int N::g() { return 0; }
22 // expected-error@-1 {{out-of-line definition of 'g' does not match any declaration in namespace 'cwg1900::N'}}
23 } // namespace cwg1900
24 
25 namespace cwg1902 { // cwg1902: 3.7
26   struct A {};
27   struct B {
28     B(A); // #cwg1902-B-A
29     B() = delete; // #cwg1902-B-ctor
30     // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
31     B(const B&) = delete; // #cwg1902-B-copy-ctor
32     // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
33     operator A();
34   };
35 
36   extern B b1;
37   B b2(b1);
38   // expected-error@-1 {{call to deleted constructor of 'B'}}
39   //   expected-note@#cwg1902-B-copy-ctor {{'B' has been explicitly marked deleted here}}
40 
41 #if __cplusplus >= 201103L
42   // This is ambiguous, even though calling the B(const B&) constructor would
43   // both directly and indirectly call a deleted function.
44   B b({});
45   // since-cxx11-error@-1 {{call to constructor of 'B' is ambiguous}}
46   //   since-cxx11-note@#cwg1902-B-A {{candidate constructor}}
47   //   since-cxx11-note@#cwg1902-B-copy-ctor {{candidate constructor has been explicitly deleted}}
48 #endif
49 } // namespace cwg1902
50 
51 namespace cwg1903 { // cwg1903: 2.7
52   namespace A {
53     struct a {};
54     int a;
55     namespace B {
56       int b;
57     }
58     using namespace B;
59     namespace {
60       int c;
61     }
62     namespace D {
63       int d;
64     }
65     using D::d;
66   }
67   namespace X {
68     using A::a;
69     using A::b;
70     using A::c;
71     using A::d;
72     struct a *p;
73   }
74 } // namespace cwg1903
75 
76 namespace cwg1909 { // cwg1909: 3.7
77   struct A {
78     template<typename T> struct A {};
79     // expected-error@-1 {{member 'A' has the same name as its class}}
80   };
81   struct B {
82     template<typename T> void B() {}
83     // expected-error@-1 {{constructor cannot have a return type}}
84   };
85   struct C {
86     template<typename T> static int C;
87     // expected-error@-1 {{member 'C' has the same name as its class}}
88     // cxx98-11-error@-2 {{variable templates are a C++14 extension}}
89   };
90   struct D {
91     template<typename T> using D = int;
92     // cxx98-error@-1 {{alias declarations are a C++11 extension}}
93     // expected-error@-2 {{member 'D' has the same name as its class}}
94   };
95 } // namespace cwg1909
96 
97 namespace cwg1918 { // cwg1918: no
98 template<typename T> struct A {
99   class B {
100     class C {};
101   };
102 };
103 class X {
104   static int x;
105   // FIXME: this is ill-formed, because A<T>::B::C does not end with a simple-template-id
106   template <typename T>
107   friend class A<T>::B::C;
108   // expected-warning@-1 {{dependent nested name specifier 'A<T>::B::' for friend class declaration is not supported; turning off access control for 'X'}}
109 };
110 template<> struct A<int> {
111   typedef struct Q B;
112 };
113 struct Q {
114   class C {
115     // FIXME: 'f' is not a friend, so 'X::x' is not accessible
116     int f() { return X::x; }
117   };
118 };
119 } // namespace cwg1918
120 
121 namespace cwg1940 { // cwg1940: 3.5
122 #if __cplusplus >= 201103L
123 static union {
124   static_assert(true, "");  // ok
125   static_assert(false, "");
126   // since-cxx11-error@-1 {{static assertion failed}}
127   int not_empty;
128 };
129 #endif
130 } // namespace cwg1918
131 
132 namespace cwg1941 { // cwg1941: 3.9
133 #if __cplusplus >= 201402L
134 template<typename X>
135 struct base {
136   template<typename T>
137   base(T a, T b, decltype(void(*T()), 0) = 0) {
138     while (a != b) (void)*a++;
139   }
140 
141   template<typename T>
142   base(T a, X x, decltype(void(T(0) * 1), 0) = 0) {
143     for (T n = 0; n != a; ++n) (void)X(x);
144   }
145 };
146 
147 struct derived : base<int> {
148   using base::base;
149 };
150 
151 struct iter {
152   iter operator++(int);
153   int operator*();
154   friend bool operator!=(iter, iter);
155 } it, end;
156 
157 derived d1(it, end);
158 derived d2(42, 9);
159 #endif
160 } // namespace cwg1941
161 
162 namespace cwg1945 { // cwg1945: no
163 template<typename T> struct A {
164   class B {
165     class C {};
166   };
167 };
168 class X {
169   static int x;
170   // FIXME: this is ill-formed, because A<T>::B::C does not end with a simple-template-id
171   template <typename T>
172   friend class A<T>::B::C;
173   // expected-warning@-1 {{dependent nested name specifier 'A<T>::B::' for friend class declaration is not supported; turning off access control for 'X'}}
174 };
175 } // namespace cwg1945
176 
177 namespace cwg1947 { // cwg1947: 3.5
178 #if __cplusplus >= 201402L
179 unsigned o = 0'01;  // ok
180 unsigned b = 0b'01;
181 // since-cxx14-error@-1 {{invalid digit 'b' in octal constant}}
182 unsigned x = 0x'01;
183 // since-cxx14-error@-1 {{invalid suffix 'x'01' on integer constant}}
184 #endif
185 } // namespace cwg1947
186 
187 #if __cplusplus >= 201103L
188 // cwg1948: 3.5
189 // FIXME: This diagnostic could be improved.
190 void *operator new(__SIZE_TYPE__) noexcept { return nullptr; }
191 // since-cxx11-error@-1 {{exception specification in declaration does not match previous declaration}}
192 #endif
193 
194 namespace cwg1959 { // cwg1959: 3.9
195 #if __cplusplus >= 201103L
196   struct b;
197   struct c;
198   struct a {
199     a() = default;
200     a(const a &) = delete; // #cwg1959-copy-ctor
201     a(const b &) = delete; // not inherited
202     a(c &&) = delete; // #cwg1959-move-ctor
203     template<typename T> a(T) = delete; // #cwg1959-temp-ctor
204   };
205 
206   struct b : a { // #cwg1959-b
207     using a::a; // #cwg1959-using-a
208   };
209 
210   a x;
211   // FIXME: As a resolution to an open DR against P0136R0, we disallow
212   // use of inherited constructors to construct from a single argument
213   // where the base class is reference-related to the argument type.
214   b y = x;
215   // since-cxx11-error@-1 {{no viable conversion from 'a' to 'b'}}
216   //   since-cxx11-note@#cwg1959-move-ctor {{candidate inherited constructor not viable: no known conversion from 'a' to 'c &&' for 1st argument}}
217   //   since-cxx11-note@#cwg1959-using-a {{constructor from base class 'a' inherited here}}
218   //   since-cxx11-note@#cwg1959-b {{candidate constructor (the implicit copy constructor) not viable: cannot bind base class object of type 'a' to derived class reference 'const b &' for 1st argument}}
219   //   since-cxx11-note@#cwg1959-temp-ctor {{candidate template ignored: instantiation would take its own class type by value}}
220   //   since-cxx11-note@#cwg1959-using-a {{constructor from base class 'a' inherited here}}
221   b z = z;
222   // since-cxx11-error@-1 {{call to implicitly-deleted copy constructor of 'b'}}
223   //   since-cxx11-note@#cwg1959-b {{copy constructor of 'b' is implicitly deleted because base class 'a' has a deleted copy constructor}}
224   //   since-cxx11-note@#cwg1959-copy-ctor {{'a' has been explicitly marked deleted here}}
225 
226   struct c : a {
227     using a::a;
228     c(const c &);
229   };
230   // FIXME: As a resolution to an open DR against P0136R0, we disallow
231   // use of inherited constructors to construct from a single argument
232   // where the base class is reference-related to the argument type.
233   c q(static_cast<c&&>(q));
234 #endif
235 } // namespace cwg1959
236 
237 namespace cwg1960 { // cwg1960: no
238 struct A {
239 void f() {}
240 protected:
241 void g() {}
242 };
243 
244 struct B: A {
245 private:
246 using A::f;
247 using A::g;
248 };
249 
250 struct C : B {
251 // FIXME: both declarations are ill-formed, because A::f and A::g
252 // are not accessible.
253 using A::f;
254 using A::g;
255 };
256 } // namespace cwg1960
257 
258 namespace cwg1966 { // cwg1966: 11
259 #if __cplusplus >= 201103L
260   struct A {
261     enum E : int {1};
262     // since-cxx11-error@-1 {{expected identifier}} (not bit-field)
263   };
264   auto *p1 = new enum E : int;
265   // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}}
266   auto *p2 = new enum F : int {};
267   // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}}
268   auto *p3 = true ? new enum G : int {};
269   // since-cxx11-error@-1 {{ISO C++ forbids forward references to 'enum' types}}
270   // since-cxx11-error@-2 {{allocation of incomplete type 'enum G'}}
271   //   since-cxx11-note@-3 {{forward declaration of 'cwg1966::G'}}
272   auto h() -> enum E : int {};
273   // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}}
274 
275   enum X : enum Y : int {} {};
276   // since-cxx11-error@-1 {{'cwg1966::Y' cannot be defined in a type specifier}}
277   struct Q {
278     // FIXME: can we emit something nicer than that?
279     enum X : enum Y : int {} {};
280     // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
281     // since-cxx11-error@-2 {{non-integral type 'enum Y' is an invalid underlying type}}
282     // since-cxx11-error@-3 {{anonymous bit-field cannot have a default member initializer}}
283   };
284 #endif
285 } // namespace cwg1966
286 
287 namespace cwg1968 { // cwg1968: no
288 #if __cplusplus >= 201103L
289   // FIXME: According to CWG1968, both of these should be considered
290   // non-constant.
291   static_assert(&typeid(int) == &typeid(int), "");
292 
293   constexpr const std::type_info *f() { return &typeid(int); }
294   static_assert(f() == f(), "");
295 #endif
296 } // namespace cwg1968
297 
298 namespace cwg1991 { // cwg1991: 3.9
299 #if __cplusplus >= 201103L
300   struct A {
301     A(int, int) = delete;
302   };
303 
304   struct B : A {
305     using A::A;
306     B(int, int, int = 0);
307   };
308 
309   // FIXME: As a resolution to an open DR against P0136R1, we treat derived
310   // class constructors as better than base class constructors in the presence
311   // of ambiguity.
312   B b(0, 0); // ok, calls B constructor
313 #endif
314 } // namespace cwg1991
315 
316 // cwg1994: dup 529
317