xref: /llvm-project/clang/test/CXX/drs/cwg23xx.cpp (revision 3972ed57088f6515b787d7d38dec03dc74e51827)
1743c84bbSVlad Serebrennikov // RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
2743c84bbSVlad Serebrennikov // RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
3743c84bbSVlad Serebrennikov // RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx11-14,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
4743c84bbSVlad Serebrennikov // RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
5743c84bbSVlad Serebrennikov // RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
6743c84bbSVlad Serebrennikov // RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
7743c84bbSVlad Serebrennikov // RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
8d358b2deSVlad Serebrennikov 
9a760df31SMital Ashok namespace std {
10a760df31SMital Ashok   __extension__ typedef __SIZE_TYPE__ size_t;
11a760df31SMital Ashok 
12a760df31SMital Ashok   template<typename E> struct initializer_list {
13a760df31SMital Ashok     const E *p; size_t n;
14a760df31SMital Ashok     initializer_list(const E *p, size_t n);
15a760df31SMital Ashok     initializer_list();
16a760df31SMital Ashok   };
17a760df31SMital Ashok }
18a760df31SMital Ashok 
19d358b2deSVlad Serebrennikov namespace cwg2303 { // cwg2303: 12
20463e61a0SVlad Serebrennikov #if __cplusplus >= 201103L
21d358b2deSVlad Serebrennikov template <typename... T>
22d358b2deSVlad Serebrennikov struct A;
23d358b2deSVlad Serebrennikov template <>
24d358b2deSVlad Serebrennikov struct A<> {};
25d358b2deSVlad Serebrennikov template <typename T, typename... Ts>
26d358b2deSVlad Serebrennikov struct A<T, Ts...> : A<Ts...> {};
27d358b2deSVlad Serebrennikov struct B : A<int, int> {};
28d358b2deSVlad Serebrennikov struct C : A<int, int>, A<int> {};
29d358b2deSVlad Serebrennikov /* since-cxx11-warning@-1 {{direct base 'A<int>' is inaccessible due to ambiguity:
30d358b2deSVlad Serebrennikov     struct cwg2303::C -> A<int, int> -> A<int>
31d358b2deSVlad Serebrennikov     struct cwg2303::C -> A<int>}} */
32d358b2deSVlad Serebrennikov struct D : A<int>, A<int, int> {};
33d358b2deSVlad Serebrennikov /* since-cxx11-warning@-1 {{direct base 'A<int>' is inaccessible due to ambiguity:
34d358b2deSVlad Serebrennikov     struct cwg2303::D -> A<int>
35d358b2deSVlad Serebrennikov     struct cwg2303::D -> A<int, int> -> A<int>}} */
36d358b2deSVlad Serebrennikov struct E : A<int, int> {};
37d358b2deSVlad Serebrennikov struct F : B, E {};
38d358b2deSVlad Serebrennikov 
39d358b2deSVlad Serebrennikov template <typename... T>
40d358b2deSVlad Serebrennikov void f(const A<T...> &) {
41d358b2deSVlad Serebrennikov   static_assert(sizeof...(T) == 2, "Should only match A<int,int>");
42d358b2deSVlad Serebrennikov }
43d358b2deSVlad Serebrennikov template <typename... T>
44d358b2deSVlad Serebrennikov void f2(const A<T...> *);
45d358b2deSVlad Serebrennikov 
46d358b2deSVlad Serebrennikov void g() {
47d358b2deSVlad Serebrennikov   f(B{}); // This is no longer ambiguous.
48d358b2deSVlad Serebrennikov   B b;
49d358b2deSVlad Serebrennikov   f2(&b);
50d358b2deSVlad Serebrennikov   f(C{});
51d358b2deSVlad Serebrennikov   f(D{});
52d358b2deSVlad Serebrennikov   f(F{});
53d358b2deSVlad Serebrennikov   /* since-cxx11-error@-1 {{ambiguous conversion from derived class 'const F' to base class 'const A<int, int>':
54d358b2deSVlad Serebrennikov     struct cwg2303::F -> B -> A<int, int>
55d358b2deSVlad Serebrennikov     struct cwg2303::F -> E -> A<int, int>}} */
56d358b2deSVlad Serebrennikov }
57d358b2deSVlad Serebrennikov #endif
58463e61a0SVlad Serebrennikov } // namespace cwg2303
59d358b2deSVlad Serebrennikov 
60d542eb7aSVlad Serebrennikov namespace cwg2304 { // cwg2304: 2.8
61d542eb7aSVlad Serebrennikov template<typename T> void foo(T, int);
62d542eb7aSVlad Serebrennikov template<typename T> void foo(T&, ...);
63d542eb7aSVlad Serebrennikov struct Q; // #cwg2304-Q
64d542eb7aSVlad Serebrennikov void fn1(Q &data_vectors) {
65d542eb7aSVlad Serebrennikov   foo(data_vectors, 0);
66d542eb7aSVlad Serebrennikov   // expected-error@-1 {{argument type 'cwg2304::Q' is incomplete}}
67d542eb7aSVlad Serebrennikov   //   expected-note@#cwg2304-Q {{forward declaration of 'cwg2304::Q'}}
68d542eb7aSVlad Serebrennikov }
69d542eb7aSVlad Serebrennikov } // namespace cwg2304
70d542eb7aSVlad Serebrennikov 
71d542eb7aSVlad Serebrennikov namespace cwg2310 { // cwg2310: partial
72d542eb7aSVlad Serebrennikov #if __cplusplus >= 201103L
73d542eb7aSVlad Serebrennikov template<typename A, typename B>
74d542eb7aSVlad Serebrennikov struct check_derived_from {
75d542eb7aSVlad Serebrennikov   static A a;
76d542eb7aSVlad Serebrennikov   // FIXME: all 3 examples should be rejected in all language modes.
77d542eb7aSVlad Serebrennikov   // FIXME: we should test this in 98 mode.
78d542eb7aSVlad Serebrennikov   // FIXME: we accept this when MSVC triple is used
79d542eb7aSVlad Serebrennikov   static constexpr B *p = &a;
80d542eb7aSVlad Serebrennikov #if !defined(_WIN32) || defined(__MINGW32__)
81d542eb7aSVlad Serebrennikov   // cxx11-14-error@-2 {{cannot initialize a variable of type 'cwg2310::X *const' with an rvalue of type 'cwg2310::Z *'}}
82d542eb7aSVlad Serebrennikov   //   cxx11-14-note@#cwg2310-X {{in instantiation of template class 'cwg2310::check_derived_from<cwg2310::Z, cwg2310::X>' requested here}}
83d542eb7aSVlad Serebrennikov   // cxx11-14-error@-4 {{cannot initialize a variable of type 'cwg2310::Y *const' with an rvalue of type 'cwg2310::Z *'}}
84d542eb7aSVlad Serebrennikov   //   cxx11-14-note@#cwg2310-Y {{in instantiation of template class 'cwg2310::check_derived_from<cwg2310::Z, cwg2310::Y>' requested here}}
85d542eb7aSVlad Serebrennikov #endif
86d542eb7aSVlad Serebrennikov };
87d542eb7aSVlad Serebrennikov 
88d542eb7aSVlad Serebrennikov struct W {};
89d542eb7aSVlad Serebrennikov struct X {};
90d542eb7aSVlad Serebrennikov struct Y {};
91d542eb7aSVlad Serebrennikov struct Z : W,
92d542eb7aSVlad Serebrennikov   X, check_derived_from<Z, X>, // #cwg2310-X
93d542eb7aSVlad Serebrennikov   check_derived_from<Z, Y>, Y  // #cwg2310-Y
94d542eb7aSVlad Serebrennikov {
95d542eb7aSVlad Serebrennikov   // FIXME: It was properly rejected before, but we're crashing since Clang 11 in C++11 and C++14 modes.
96d542eb7aSVlad Serebrennikov   //        See https://github.com/llvm/llvm-project/issues/59920
97d542eb7aSVlad Serebrennikov #if __cplusplus >= 201703L
98d542eb7aSVlad Serebrennikov   check_derived_from<Z, W> cdf;
99d542eb7aSVlad Serebrennikov #endif
100d542eb7aSVlad Serebrennikov };
101d542eb7aSVlad Serebrennikov #endif
102d542eb7aSVlad Serebrennikov } // namespace cwg2310
103d542eb7aSVlad Serebrennikov 
104d358b2deSVlad Serebrennikov // cwg2331: na
105d358b2deSVlad Serebrennikov // cwg2335 is in cwg2335.cxx
106d358b2deSVlad Serebrennikov 
107a760df31SMital Ashok namespace cwg2311 {  // cwg2311 is open with no proposed resolution
108a760df31SMital Ashok #if __cplusplus >= 201707L
109a760df31SMital Ashok template<typename T>
110a760df31SMital Ashok void test() {
111a760df31SMital Ashok   // Ensure none of these try to call a move constructor.
112a760df31SMital Ashok   T a = T{T(0)};
113a760df31SMital Ashok   T b{T(0)};
114a760df31SMital Ashok   auto c{T(0)};
115a760df31SMital Ashok   T d = {T(0)};
116a760df31SMital Ashok   auto e = {T(0)};
117a760df31SMital Ashok #if __cplusplus >= 202302L
118a760df31SMital Ashok   auto f = auto{T(0)};
119a760df31SMital Ashok #endif
120a760df31SMital Ashok   void(*fn)(T);
121a760df31SMital Ashok   fn({T(0)});
122a760df31SMital Ashok }
123a760df31SMital Ashok 
124a760df31SMital Ashok struct NonMovable {
125a760df31SMital Ashok   NonMovable(int);
126a760df31SMital Ashok   NonMovable(NonMovable&&) = delete;
127a760df31SMital Ashok };
128a760df31SMital Ashok struct NonMovableNonApplicableIList {
129a760df31SMital Ashok   NonMovableNonApplicableIList(int);
130a760df31SMital Ashok   NonMovableNonApplicableIList(NonMovableNonApplicableIList&&) = delete;
131a760df31SMital Ashok   NonMovableNonApplicableIList(std::initializer_list<int>);
132a760df31SMital Ashok };
133a760df31SMital Ashok struct ExplicitMovable {
134a760df31SMital Ashok   ExplicitMovable(int);
135a760df31SMital Ashok   explicit ExplicitMovable(ExplicitMovable&&);
136a760df31SMital Ashok };
137a760df31SMital Ashok struct ExplicitNonMovable {
138a760df31SMital Ashok   ExplicitNonMovable(int);
139a760df31SMital Ashok   explicit ExplicitNonMovable(ExplicitNonMovable&&) = delete;
140a760df31SMital Ashok };
141a760df31SMital Ashok struct ExplicitNonMovableNonApplicableIList {
142a760df31SMital Ashok   ExplicitNonMovableNonApplicableIList(int);
143a760df31SMital Ashok   explicit ExplicitNonMovableNonApplicableIList(ExplicitNonMovableNonApplicableIList&&) = delete;
144a760df31SMital Ashok   ExplicitNonMovableNonApplicableIList(std::initializer_list<int>);
145a760df31SMital Ashok };
146a760df31SMital Ashok struct CopyOnly {
147a760df31SMital Ashok   CopyOnly(int);
148a760df31SMital Ashok   CopyOnly(const CopyOnly&);
149a760df31SMital Ashok   CopyOnly(CopyOnly&&) = delete;
150a760df31SMital Ashok };
151a760df31SMital Ashok struct ExplicitCopyOnly {
152a760df31SMital Ashok   ExplicitCopyOnly(int);
153a760df31SMital Ashok   explicit ExplicitCopyOnly(const ExplicitCopyOnly&);
154a760df31SMital Ashok   explicit ExplicitCopyOnly(ExplicitCopyOnly&&) = delete;
155a760df31SMital Ashok };
156a760df31SMital Ashok 
157a760df31SMital Ashok template void test<NonMovable>();
158a760df31SMital Ashok template void test<NonMovableNonApplicableIList>();
159a760df31SMital Ashok template void test<ExplicitMovable>();
160a760df31SMital Ashok template void test<ExplicitNonMovable>();
161a760df31SMital Ashok template void test<ExplicitNonMovableNonApplicableIList>();
162a760df31SMital Ashok template void test<CopyOnly>();
163a760df31SMital Ashok template void test<ExplicitCopyOnly>();
164a760df31SMital Ashok 
165a760df31SMital Ashok struct any {
166a760df31SMital Ashok     template<typename T>
167a760df31SMital Ashok     any(T&&);
168a760df31SMital Ashok };
169a760df31SMital Ashok 
170a760df31SMital Ashok template<typename T>
171a760df31SMital Ashok struct X {
172a760df31SMital Ashok     X();
173a760df31SMital Ashok     X(T) = delete; // #cwg2311-X
174a760df31SMital Ashok };
175a760df31SMital Ashok 
176a760df31SMital Ashok X<std::initializer_list<any>> x{ X<std::initializer_list<any>>() };
177a760df31SMital Ashok // since-cxx17-error@-1 {{call to deleted constructor of 'X<std::initializer_list<any>>'}}
178a760df31SMital Ashok //   since-cxx17-note@#cwg2311-X {{'X' has been explicitly marked deleted here}}
179a760df31SMital Ashok 
180a760df31SMital Ashok // Per the currently implemented resolution, this does not apply to std::initializer_list.
181a760df31SMital Ashok // An initializer list initialized from `{ e }` always has exactly one element constructed
182a760df31SMital Ashok // from `e`, where previously that could have been a copy of an init list or `e.operator std::initializer_list()`
183a760df31SMital Ashok struct InitListCtor {
184a760df31SMital Ashok   InitListCtor(int);
185a760df31SMital Ashok   InitListCtor(InitListCtor&&) = delete;
186a760df31SMital Ashok   InitListCtor(std::initializer_list<InitListCtor>) = delete; // #cwg2311-InitListCtor
187a760df31SMital Ashok };
188a760df31SMital Ashok 
189a760df31SMital Ashok std::initializer_list<InitListCtor> i;
190a760df31SMital Ashok auto j = std::initializer_list<InitListCtor>{ i };
191a760df31SMital Ashok // since-cxx17-error@-1 {{conversion function from 'std::initializer_list<InitListCtor>' to 'const cwg2311::InitListCtor' invokes a deleted function}}
192a760df31SMital Ashok //   since-cxx17-note@#cwg2311-InitListCtor {{'InitListCtor' has been explicitly marked deleted here}}
193a760df31SMital Ashok #endif
194463e61a0SVlad Serebrennikov } // namespace cwg2311
195a760df31SMital Ashok 
196d358b2deSVlad Serebrennikov namespace cwg2338 { // cwg2338: 12
197463e61a0SVlad Serebrennikov #if __cplusplus >= 201103L
198d358b2deSVlad Serebrennikov namespace B {
199d358b2deSVlad Serebrennikov enum E : bool { Zero, One };
200d358b2deSVlad Serebrennikov static_assert((int)(E)2 == 1, "");
201d358b2deSVlad Serebrennikov } // namespace B
202d358b2deSVlad Serebrennikov namespace D {
203d358b2deSVlad Serebrennikov enum class E : bool { Zero, One };
204d358b2deSVlad Serebrennikov static_assert((int)(E)2 == 1, "");
205d358b2deSVlad Serebrennikov } // namespace D
206d358b2deSVlad Serebrennikov #endif
207463e61a0SVlad Serebrennikov } // namespace cwg2338
208d358b2deSVlad Serebrennikov 
209d358b2deSVlad Serebrennikov namespace cwg2346 { // cwg2346: 11
210d358b2deSVlad Serebrennikov   void test() {
211d358b2deSVlad Serebrennikov     const int i2 = 0;
212d358b2deSVlad Serebrennikov     extern void h2b(int x = i2 + 0); // ok, not odr-use
213d358b2deSVlad Serebrennikov   }
214463e61a0SVlad Serebrennikov } // namespace cwg2346
215d358b2deSVlad Serebrennikov 
2169d739e54SMital Ashok namespace cwg2351 { // cwg2351: 20
2179d739e54SMital Ashok #if __cplusplus >= 201103L
2189d739e54SMital Ashok   static_assert((void{}, true), "");
2199d739e54SMital Ashok 
2209d739e54SMital Ashok   void f() {
2219d739e54SMital Ashok     return void{};
2229d739e54SMital Ashok   }
2239d739e54SMital Ashok 
2249d739e54SMital Ashok   template<typename T>
2259d739e54SMital Ashok   void g() {
2269d739e54SMital Ashok     return T{};
2279d739e54SMital Ashok   }
2289d739e54SMital Ashok   template void g<void>();
2299d739e54SMital Ashok   template void g<const void>();
2309d739e54SMital Ashok 
2319d739e54SMital Ashok   void h() {
2329d739e54SMital Ashok     return {};
2339d739e54SMital Ashok     // since-cxx11-error@-1 {{void function 'h' must not return a value}}
2349d739e54SMital Ashok   }
2359d739e54SMital Ashok 
2369d739e54SMital Ashok   template<typename T, int... I>
2379d739e54SMital Ashok   T i() {
2389d739e54SMital Ashok     return T{I...};
2399d739e54SMital Ashok   }
2409d739e54SMital Ashok   template void i<void>();
2419d739e54SMital Ashok   template const void i<const void>();
2429d739e54SMital Ashok 
2439d739e54SMital Ashok   static_assert((void({}), true), "");
2449d739e54SMital Ashok   // since-cxx11-error@-1 {{cannot initialize non-class type 'void' with a parenthesized initializer list}}
2459d739e54SMital Ashok #else
2469d739e54SMital Ashok   int I = (void{}, 0);
2479d739e54SMital Ashok   // cxx98-error@-1 {{expected ')'}}
2489d739e54SMital Ashok   //   cxx98-note@-2 {{to match this '('}}
2499d739e54SMital Ashok   // cxx98-error@-3 {{expected expression}}
2509d739e54SMital Ashok #endif
251463e61a0SVlad Serebrennikov } // namespace cwg2351
2529d739e54SMital Ashok 
253d358b2deSVlad Serebrennikov namespace cwg2352 { // cwg2352: 10
254d358b2deSVlad Serebrennikov   int **p;
255d358b2deSVlad Serebrennikov   const int *const *const &f1() { return p; }
256d358b2deSVlad Serebrennikov   int *const *const &f2() { return p; }
257d358b2deSVlad Serebrennikov   int **const &f3() { return p; }
258d358b2deSVlad Serebrennikov 
259d358b2deSVlad Serebrennikov   const int **const &f4() { return p; }
260d358b2deSVlad Serebrennikov   // expected-error@-1 {{reference to type 'const int **const' could not bind to an lvalue of type 'int **'}}
261d358b2deSVlad Serebrennikov   const int *const *&f5() { return p; }
262d358b2deSVlad Serebrennikov   // expected-error@-1 {{binding reference of type 'const int *const *' to value of type 'int **' not permitted due to incompatible qualifiers}}
263d358b2deSVlad Serebrennikov 
264d358b2deSVlad Serebrennikov   // FIXME: We permit this as a speculative defect resolution, allowing
265d358b2deSVlad Serebrennikov   // qualification conversions when forming a glvalue conditional expression.
266d358b2deSVlad Serebrennikov   const int * const * const q = 0;
267d358b2deSVlad Serebrennikov   __typeof(&(true ? p : q)) x = &(true ? p : q);
268d358b2deSVlad Serebrennikov 
269d358b2deSVlad Serebrennikov   // FIXME: Should we compute the composite pointer type here and produce an
270d358b2deSVlad Serebrennikov   // lvalue of type 'const int *const * const'?
271d358b2deSVlad Serebrennikov   const int * const * r;
272d358b2deSVlad Serebrennikov   void *y = &(true ? p : r);
273d358b2deSVlad Serebrennikov   // expected-error@-1 {{rvalue of type 'const int *const *'}}
274d358b2deSVlad Serebrennikov 
275d358b2deSVlad Serebrennikov   // FIXME: We order these as a speculative defect resolution.
276d358b2deSVlad Serebrennikov   void f(const int * const * const &r);
277d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L
278d358b2deSVlad Serebrennikov   constexpr
279d358b2deSVlad Serebrennikov #endif
280d358b2deSVlad Serebrennikov   int *const *const &f(int * const * const &r) { return r; }
281d358b2deSVlad Serebrennikov 
282d358b2deSVlad Serebrennikov   // No temporary is created here.
283d358b2deSVlad Serebrennikov   int *const *const &check_f = f(p);
284d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L
285d358b2deSVlad Serebrennikov   static_assert(&p == &check_f, "");
286d358b2deSVlad Serebrennikov #endif
287743c84bbSVlad Serebrennikov } // namespace cwg2352
288d358b2deSVlad Serebrennikov 
289d358b2deSVlad Serebrennikov namespace cwg2354 { // cwg2354: 15
290d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L
291d358b2deSVlad Serebrennikov enum alignas(64) A {};
292d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{'alignas' attribute cannot be applied to an enumeration}}
293d358b2deSVlad Serebrennikov enum struct alignas(64) B {};
294d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{'alignas' attribute cannot be applied to an enumeration}}
295d358b2deSVlad Serebrennikov #endif
296d358b2deSVlad Serebrennikov } // namespace cwg2354
297d358b2deSVlad Serebrennikov 
298d358b2deSVlad Serebrennikov namespace cwg2356 { // cwg2356: 4
299d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L
300d358b2deSVlad Serebrennikov struct A {
301d358b2deSVlad Serebrennikov   A();
302d358b2deSVlad Serebrennikov   A(A &&);                        // #1
303d358b2deSVlad Serebrennikov   template<typename T> A(T &&);   // #2
304d358b2deSVlad Serebrennikov };
305d358b2deSVlad Serebrennikov struct B : A {
306d358b2deSVlad Serebrennikov   using A::A;
307d358b2deSVlad Serebrennikov   B(const B &);                   // #3
308d358b2deSVlad Serebrennikov   B(B &&) = default;              // #4, implicitly deleted
309d358b2deSVlad Serebrennikov   // since-cxx11-warning@-1 {{explicitly defaulted move constructor is implicitly deleted}}
310d358b2deSVlad Serebrennikov   //   since-cxx11-note@#cwg2356-X {{move constructor of 'B' is implicitly deleted because field 'x' has a deleted move constructor}}
311d358b2deSVlad Serebrennikov   //   since-cxx11-note@#cwg2356-X {{'X' has been explicitly marked deleted here}}
312d358b2deSVlad Serebrennikov   //   since-cxx11-note@-4 {{replace 'default' with 'delete'}}
313d358b2deSVlad Serebrennikov 
314d358b2deSVlad Serebrennikov   struct X { X(X &&) = delete; } x; // #cwg2356-X
315d358b2deSVlad Serebrennikov };
316d358b2deSVlad Serebrennikov extern B b1;
317d358b2deSVlad Serebrennikov B b2 = static_cast<B&&>(b1);      // calls #3: #1, #2, and #4 are not viable
318d358b2deSVlad Serebrennikov struct C { operator B&&(); };
319d358b2deSVlad Serebrennikov B b3 = C();                       // calls #3
320d358b2deSVlad Serebrennikov #endif
321463e61a0SVlad Serebrennikov } // namespace cwg2356
322d358b2deSVlad Serebrennikov 
323d358b2deSVlad Serebrennikov namespace cwg2358 { // cwg2358: 16
324463e61a0SVlad Serebrennikov #if __cplusplus >= 201402L
325d358b2deSVlad Serebrennikov   void f2() {
326d358b2deSVlad Serebrennikov     int i = 1;
327d358b2deSVlad Serebrennikov     void g1(int = [xxx=1] { return xxx; }());  // OK
328d358b2deSVlad Serebrennikov     void g2(int = [xxx=i] { return xxx; }());
329d358b2deSVlad Serebrennikov     // since-cxx14-error@-1 {{default argument references local variable 'i' of enclosing function}}
330d358b2deSVlad Serebrennikov   }
331d358b2deSVlad Serebrennikov #endif
332463e61a0SVlad Serebrennikov } // namespace cwg2358
333d358b2deSVlad Serebrennikov 
334d358b2deSVlad Serebrennikov // CWG2363 was closed as NAD, but its resolution does affirm that
335d358b2deSVlad Serebrennikov // a friend declaration cannot have an opaque-enumm-specifier.
336*14ba3f9dSVlad Serebrennikov namespace cwg2363 { // cwg2363: 19
337d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L
338d358b2deSVlad Serebrennikov enum class E0;
339d358b2deSVlad Serebrennikov enum E1 : int;
340d358b2deSVlad Serebrennikov 
341d358b2deSVlad Serebrennikov struct A {
342d358b2deSVlad Serebrennikov   friend enum class E0;
343d358b2deSVlad Serebrennikov   // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 'enum class'}}
344eff12650SVlad Serebrennikov   // since-cxx11-error@-2 {{elaborated enum specifier cannot be declared as a friend}}
345eff12650SVlad Serebrennikov   //   since-cxx11-note@-3 {{remove 'enum class' to befriend an enum}}
346d358b2deSVlad Serebrennikov 
347d358b2deSVlad Serebrennikov   friend enum E0;
348eff12650SVlad Serebrennikov   // since-cxx11-error@-1 {{elaborated enum specifier cannot be declared as a friend}}
349eff12650SVlad Serebrennikov   //   since-cxx11-note@-2 {{remove 'enum' to befriend an enum}}
350d358b2deSVlad Serebrennikov 
351d358b2deSVlad Serebrennikov   friend enum class E1;
352d358b2deSVlad Serebrennikov   // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 'enum class'}}
353eff12650SVlad Serebrennikov   // since-cxx11-error@-2 {{elaborated enum specifier cannot be declared as a friend}}
354eff12650SVlad Serebrennikov   //   since-cxx11-note@-3 {{remove 'enum class' to befriend an enum}}
355d358b2deSVlad Serebrennikov 
356d358b2deSVlad Serebrennikov   friend enum E1;
357eff12650SVlad Serebrennikov   // since-cxx11-error@-1 {{elaborated enum specifier cannot be declared as a friend}}
358eff12650SVlad Serebrennikov   //   since-cxx11-note@-2 {{remove 'enum' to befriend an enum}}
359d358b2deSVlad Serebrennikov 
360d358b2deSVlad Serebrennikov   friend enum class E2;
361d358b2deSVlad Serebrennikov   // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 'enum class'}}
362eff12650SVlad Serebrennikov   // since-cxx11-error@-2 {{elaborated enum specifier cannot be declared as a friend}}
363eff12650SVlad Serebrennikov   //   since-cxx11-note@-3 {{remove 'enum class' to befriend an enum}}
364d358b2deSVlad Serebrennikov };
365d358b2deSVlad Serebrennikov #endif
366d358b2deSVlad Serebrennikov } // namespace cwg2363
367d358b2deSVlad Serebrennikov 
368d358b2deSVlad Serebrennikov namespace cwg2370 { // cwg2370: no
369d358b2deSVlad Serebrennikov namespace N {
370d358b2deSVlad Serebrennikov typedef int type;
371d358b2deSVlad Serebrennikov void g(type);
372d358b2deSVlad Serebrennikov void h(type);
373d358b2deSVlad Serebrennikov } // namespace N
374d358b2deSVlad Serebrennikov class C {
375d358b2deSVlad Serebrennikov   typedef N::type N_type;
376d358b2deSVlad Serebrennikov   // FIXME: `type` should be searched for in N
377d358b2deSVlad Serebrennikov   // friend void N::g(type);
378d358b2deSVlad Serebrennikov   friend void N::h(N_type);
379d358b2deSVlad Serebrennikov };
380d358b2deSVlad Serebrennikov } // namespace cwg2370
381d358b2deSVlad Serebrennikov 
382463e61a0SVlad Serebrennikov namespace cwg2386 { // cwg2386: 9
383d358b2deSVlad Serebrennikov // Otherwise, if the qualified-id std::tuple_size<E> names a complete class
384d358b2deSVlad Serebrennikov // type **with a member value**, the expression std::tuple_size<E>::value shall
385d358b2deSVlad Serebrennikov // be a well-formed integral constant expression
386463e61a0SVlad Serebrennikov #if __cplusplus >= 201702L
387d358b2deSVlad Serebrennikov struct Bad1 { int a, b; };
388d358b2deSVlad Serebrennikov struct Bad2 { int a, b; };
389d358b2deSVlad Serebrennikov } // namespace cwg2386
390d358b2deSVlad Serebrennikov namespace std {
391d358b2deSVlad Serebrennikov template <typename T> struct tuple_size;
392d358b2deSVlad Serebrennikov template <> struct tuple_size<cwg2386::Bad1> {};
393d358b2deSVlad Serebrennikov template <> struct tuple_size<cwg2386::Bad2> {
394d358b2deSVlad Serebrennikov   static const int value = 42;
395d358b2deSVlad Serebrennikov };
396d358b2deSVlad Serebrennikov } // namespace std
397d358b2deSVlad Serebrennikov namespace cwg2386 {
398d358b2deSVlad Serebrennikov void no_value() { auto [x, y] = Bad1(); }
399d358b2deSVlad Serebrennikov void wrong_value() { auto [x, y] = Bad2(); }
400d358b2deSVlad Serebrennikov // since-cxx17-error@-1 {{type 'Bad2' decomposes into 42 elements, but only 2 names were provided}}
401d358b2deSVlad Serebrennikov #endif
402463e61a0SVlad Serebrennikov } // namespace cwg2386
403d358b2deSVlad Serebrennikov 
404d358b2deSVlad Serebrennikov // cwg2385: na
405d358b2deSVlad Serebrennikov 
406d358b2deSVlad Serebrennikov namespace cwg2387 { // cwg2387: 9
407d358b2deSVlad Serebrennikov #if __cplusplus >= 201402L
408d358b2deSVlad Serebrennikov   template<int> int a = 0;
409d358b2deSVlad Serebrennikov   extern template int a<0>; // ok
410d358b2deSVlad Serebrennikov 
411d358b2deSVlad Serebrennikov   template<int> static int b = 0;
412d358b2deSVlad Serebrennikov   extern template int b<0>;
413d358b2deSVlad Serebrennikov   // since-cxx14-error@-1 {{explicit instantiation declaration of 'b<0>' with internal linkage}}
414d358b2deSVlad Serebrennikov 
415d358b2deSVlad Serebrennikov   template<int> const int c = 0;
416d358b2deSVlad Serebrennikov   extern template const int c<0>; // ok, has external linkage despite 'const'
417d358b2deSVlad Serebrennikov 
418d358b2deSVlad Serebrennikov   template<typename T> T d = 0;
419d358b2deSVlad Serebrennikov   extern template int d<int>;
420d358b2deSVlad Serebrennikov   extern template const int d<const int>;
421d358b2deSVlad Serebrennikov #endif
422463e61a0SVlad Serebrennikov } // namespace cwg2387
423d358b2deSVlad Serebrennikov 
424c631131aSVlad Serebrennikov namespace cwg2390 { // cwg2390: 14
425c631131aSVlad Serebrennikov // Test that macro expansion of the builtin argument works.
426c631131aSVlad Serebrennikov #define C clang
427c631131aSVlad Serebrennikov #define F fallthrough
428c631131aSVlad Serebrennikov #define CF clang::fallthrough
429c631131aSVlad Serebrennikov 
430c631131aSVlad Serebrennikov #if !__has_cpp_attribute(F)
431c631131aSVlad Serebrennikov #error "doesn't have fallthrough"
432c631131aSVlad Serebrennikov #endif
433c631131aSVlad Serebrennikov 
434c631131aSVlad Serebrennikov #if !__has_cpp_attribute(C::F)
435c631131aSVlad Serebrennikov #error "doesn't have clang::fallthrough 1"
436c631131aSVlad Serebrennikov #endif
437c631131aSVlad Serebrennikov 
438c631131aSVlad Serebrennikov #if !__has_cpp_attribute(clang::F)
439c631131aSVlad Serebrennikov #error "doesn't have clang::fallthrough 2"
440c631131aSVlad Serebrennikov #endif
441c631131aSVlad Serebrennikov 
442c631131aSVlad Serebrennikov #if !__has_cpp_attribute(C::fallthrough)
443c631131aSVlad Serebrennikov #error "doesn't have clang::fallthrough 3"
444c631131aSVlad Serebrennikov #endif
445c631131aSVlad Serebrennikov 
446c631131aSVlad Serebrennikov #if !__has_cpp_attribute(CF)
447c631131aSVlad Serebrennikov #error "doesn't have clang::fallthrough 4"
448c631131aSVlad Serebrennikov #endif
449c631131aSVlad Serebrennikov 
450c631131aSVlad Serebrennikov #define FUNCLIKE1(x) clang::x
451c631131aSVlad Serebrennikov #if !__has_cpp_attribute(FUNCLIKE1(fallthrough))
452c631131aSVlad Serebrennikov #error "doesn't have clang::fallthrough through func-like macro 1"
453c631131aSVlad Serebrennikov #endif
454c631131aSVlad Serebrennikov 
455c631131aSVlad Serebrennikov #define FUNCLIKE2(x) _Clang::x
456c631131aSVlad Serebrennikov #if !__has_cpp_attribute(FUNCLIKE2(fallthrough))
457c631131aSVlad Serebrennikov #error "doesn't have clang::fallthrough through func-like macro 2"
458c631131aSVlad Serebrennikov #endif
459c631131aSVlad Serebrennikov } // namespace cwg2390
460d358b2deSVlad Serebrennikov 
461d358b2deSVlad Serebrennikov namespace cwg2394 { // cwg2394: 15
462d358b2deSVlad Serebrennikov 
463d358b2deSVlad Serebrennikov struct A {};
464d358b2deSVlad Serebrennikov const A a;
465d358b2deSVlad Serebrennikov 
466d358b2deSVlad Serebrennikov // Now allowed to default-init B.
467d358b2deSVlad Serebrennikov struct B { const A a; };
468d358b2deSVlad Serebrennikov B b;
469d358b2deSVlad Serebrennikov 
470463e61a0SVlad Serebrennikov } // namespace cwg2394
471d358b2deSVlad Serebrennikov 
472d358b2deSVlad Serebrennikov namespace cwg2396 { // cwg2396: no
473d358b2deSVlad Serebrennikov   struct A {
474d358b2deSVlad Serebrennikov     struct B;
475d358b2deSVlad Serebrennikov     operator B B::*();
476d358b2deSVlad Serebrennikov   };
477d358b2deSVlad Serebrennikov   struct B;
478d358b2deSVlad Serebrennikov 
479d358b2deSVlad Serebrennikov   // FIXME: per P1787 "Calling a conversion function" example, all of the
480d358b2deSVlad Serebrennikov   // examples below are well-formed, with B resolving to A::B, but currently
481d358b2deSVlad Serebrennikov   // it's been resolved to cwg2396::B.
482d358b2deSVlad Serebrennikov 
483d358b2deSVlad Serebrennikov   // void f(A a) { a.operator B B::*(); }
484d358b2deSVlad Serebrennikov   // void g(A a) { a.operator decltype(B()) B::*(); }
485d358b2deSVlad Serebrennikov   // void g2(A a) { a.operator B decltype(B())::*(); }
486463e61a0SVlad Serebrennikov } // namespace cwg2396
487d358b2deSVlad Serebrennikov 
488d358b2deSVlad Serebrennikov namespace cwg2397 { // cwg2397: 17
489463e61a0SVlad Serebrennikov #if __cplusplus >= 201103L
490d358b2deSVlad Serebrennikov   void foo() {
491d358b2deSVlad Serebrennikov     int a[5];
492d358b2deSVlad Serebrennikov 
493d358b2deSVlad Serebrennikov     auto (&b)[5] = a;
494d358b2deSVlad Serebrennikov     auto (*c)[5] = &a;
495d358b2deSVlad Serebrennikov   }
496463e61a0SVlad Serebrennikov #endif
497d358b2deSVlad Serebrennikov } // namespace cwg2397
498