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