xref: /llvm-project/clang/test/SemaCXX/constrained-special-member-functions.cpp (revision 0f59bee3d58f5dc7914d58aa520e65f3ba986705)
1b1c960fcSRoy Jacobson // RUN: %clang_cc1 -verify -std=c++20 %s
2b1c960fcSRoy Jacobson 
3b1c960fcSRoy Jacobson template <int N>
4b1c960fcSRoy Jacobson concept C0 = (N == 0);
5b1c960fcSRoy Jacobson template <int N>
6b1c960fcSRoy Jacobson concept C1 = (N == 1);
7b1c960fcSRoy Jacobson template <int N>
8b1c960fcSRoy Jacobson concept C2 = (N == 2);
9b1c960fcSRoy Jacobson 
10b1c960fcSRoy Jacobson // Checks are indexed by:
11b1c960fcSRoy Jacobson // Definition:
12b1c960fcSRoy Jacobson //  1. Explicitly defaulted definition
13b1c960fcSRoy Jacobson //  2. Deleted definition
14b1c960fcSRoy Jacobson //  3. User provided definition
15b1c960fcSRoy Jacobson // We have a less constrained user provided method that should not disable
16b1c960fcSRoy Jacobson // the (copyable) triviality of the type.
17b1c960fcSRoy Jacobson 
18b1c960fcSRoy Jacobson // Note that because Clang does not implement DRs 1496 and 1734, we say some
19b1c960fcSRoy Jacobson // classes are trivial when the SMFs are deleted.
20b1c960fcSRoy Jacobson 
21b1c960fcSRoy Jacobson template <int N>
22b1c960fcSRoy Jacobson struct DefaultConstructorChecker {
23b1c960fcSRoy Jacobson     DefaultConstructorChecker() requires C0<N> = default;
24b1c960fcSRoy Jacobson     DefaultConstructorChecker() requires C1<N> = delete;
25b1c960fcSRoy Jacobson     DefaultConstructorChecker() requires C2<N>;
26b1c960fcSRoy Jacobson     DefaultConstructorChecker();
27b1c960fcSRoy Jacobson };
28b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
29b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
30b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
31b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
32b1c960fcSRoy Jacobson static_assert(__is_trivial(DefaultConstructorChecker<0>));
33b1c960fcSRoy Jacobson // FIXME: DR1496
34b1c960fcSRoy Jacobson static_assert(__is_trivial(DefaultConstructorChecker<1>));
35b1c960fcSRoy Jacobson static_assert(!__is_trivial(DefaultConstructorChecker<2>));
36b1c960fcSRoy Jacobson static_assert(!__is_trivial(DefaultConstructorChecker<3>));
37b1c960fcSRoy Jacobson 
38b1c960fcSRoy Jacobson template <int N>
39b1c960fcSRoy Jacobson struct CopyConstructorChecker {
40b1c960fcSRoy Jacobson     CopyConstructorChecker(const CopyConstructorChecker&) requires C0<N> = default;
41b1c960fcSRoy Jacobson     CopyConstructorChecker(const CopyConstructorChecker&) requires C1<N> = delete;
42b1c960fcSRoy Jacobson     CopyConstructorChecker(const CopyConstructorChecker&) requires C2<N>;
43b1c960fcSRoy Jacobson     CopyConstructorChecker(const CopyConstructorChecker&);
44b1c960fcSRoy Jacobson };
45b1c960fcSRoy Jacobson 
46b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
47b1c960fcSRoy Jacobson // FIXME: DR1734
48b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
49b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
50b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
51b1c960fcSRoy Jacobson static_assert(!__is_trivial(CopyConstructorChecker<0>));
52b1c960fcSRoy Jacobson static_assert(!__is_trivial(CopyConstructorChecker<1>));
53b1c960fcSRoy Jacobson static_assert(!__is_trivial(CopyConstructorChecker<2>));
54b1c960fcSRoy Jacobson static_assert(!__is_trivial(CopyConstructorChecker<3>));
55b1c960fcSRoy Jacobson 
56b1c960fcSRoy Jacobson template <int N>
57b1c960fcSRoy Jacobson struct MoveConstructorChecker {
58b1c960fcSRoy Jacobson     MoveConstructorChecker(MoveConstructorChecker&&) requires C0<N> = default;
59b1c960fcSRoy Jacobson     MoveConstructorChecker(MoveConstructorChecker&&) requires C1<N> = delete;
60b1c960fcSRoy Jacobson     MoveConstructorChecker(MoveConstructorChecker&&) requires C2<N>;
61b1c960fcSRoy Jacobson     MoveConstructorChecker(MoveConstructorChecker&&);
62b1c960fcSRoy Jacobson };
63b1c960fcSRoy Jacobson 
64b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
65b1c960fcSRoy Jacobson // FIXME: DR1734
66b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
67b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
68b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
69b1c960fcSRoy Jacobson static_assert(!__is_trivial(MoveConstructorChecker<0>));
70b1c960fcSRoy Jacobson static_assert(!__is_trivial(MoveConstructorChecker<1>));
71b1c960fcSRoy Jacobson static_assert(!__is_trivial(MoveConstructorChecker<2>));
72b1c960fcSRoy Jacobson static_assert(!__is_trivial(MoveConstructorChecker<3>));
73b1c960fcSRoy Jacobson 
74b1c960fcSRoy Jacobson template <int N>
75b1c960fcSRoy Jacobson struct MoveAssignmentChecker {
76b1c960fcSRoy Jacobson     MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0<N> = default;
77b1c960fcSRoy Jacobson     MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1<N> = delete;
78b1c960fcSRoy Jacobson     MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2<N>;
79b1c960fcSRoy Jacobson     MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);
80b1c960fcSRoy Jacobson };
81b1c960fcSRoy Jacobson 
82b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
83b1c960fcSRoy Jacobson // FIXME: DR1734.
84b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
85b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
86b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));
87b1c960fcSRoy Jacobson static_assert(__is_trivial(MoveAssignmentChecker<0>));
88b1c960fcSRoy Jacobson // FIXME: DR1734.
89b1c960fcSRoy Jacobson static_assert(__is_trivial(MoveAssignmentChecker<1>));
90b1c960fcSRoy Jacobson static_assert(!__is_trivial(MoveAssignmentChecker<2>));
91b1c960fcSRoy Jacobson static_assert(!__is_trivial(MoveAssignmentChecker<3>));
92b1c960fcSRoy Jacobson 
93b1c960fcSRoy Jacobson template <int N>
94b1c960fcSRoy Jacobson struct CopyAssignmentChecker {
95b1c960fcSRoy Jacobson     CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C0<N> = default;
96b1c960fcSRoy Jacobson     CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C1<N> = delete;
97b1c960fcSRoy Jacobson     CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C2<N>;
98b1c960fcSRoy Jacobson     CopyAssignmentChecker& operator=(const CopyAssignmentChecker&);
99b1c960fcSRoy Jacobson };
100b1c960fcSRoy Jacobson 
101b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(CopyAssignmentChecker<0>));
102b1c960fcSRoy Jacobson // FIXME: DR1734.
103b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(CopyAssignmentChecker<1>));
104b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(CopyAssignmentChecker<2>));
105b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(CopyAssignmentChecker<3>));
106b1c960fcSRoy Jacobson static_assert(__is_trivial(CopyAssignmentChecker<0>));
107b1c960fcSRoy Jacobson // FIXME: DR1734.
108b1c960fcSRoy Jacobson static_assert(__is_trivial(CopyAssignmentChecker<1>));
109b1c960fcSRoy Jacobson static_assert(!__is_trivial(CopyAssignmentChecker<2>));
110b1c960fcSRoy Jacobson static_assert(!__is_trivial(CopyAssignmentChecker<3>));
111b1c960fcSRoy Jacobson 
112b1c960fcSRoy Jacobson 
113b1c960fcSRoy Jacobson template <int N>
114b1c960fcSRoy Jacobson struct KindComparisonChecker1 {
115b1c960fcSRoy Jacobson     KindComparisonChecker1& operator=(const KindComparisonChecker1&) requires C0<N> = default;
116b1c960fcSRoy Jacobson     KindComparisonChecker1& operator=(KindComparisonChecker1&);
117b1c960fcSRoy Jacobson };
118b1c960fcSRoy Jacobson 
119b1c960fcSRoy Jacobson template <int N>
120b1c960fcSRoy Jacobson struct KindComparisonChecker2 {
121b1c960fcSRoy Jacobson     KindComparisonChecker2& operator=(const KindComparisonChecker2&) requires C0<N> = default;
122b1c960fcSRoy Jacobson     const KindComparisonChecker2& operator=(KindComparisonChecker2&) const;
123b1c960fcSRoy Jacobson };
124b1c960fcSRoy Jacobson 
125b1c960fcSRoy Jacobson template <int N>
126b1c960fcSRoy Jacobson struct KindComparisonChecker3 {
127b1c960fcSRoy Jacobson     using Alias = KindComparisonChecker3;
128b1c960fcSRoy Jacobson     Alias& operator=(const Alias&) requires C0<N> = default;
129b1c960fcSRoy Jacobson     KindComparisonChecker3& operator=(const KindComparisonChecker3&);
130b1c960fcSRoy Jacobson };
131b1c960fcSRoy Jacobson 
132b1c960fcSRoy Jacobson static_assert(!__is_trivial(KindComparisonChecker1<0>));
133b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(KindComparisonChecker1<0>));
134b1c960fcSRoy Jacobson 
135b1c960fcSRoy Jacobson static_assert(!__is_trivial(KindComparisonChecker2<0>));
136b1c960fcSRoy Jacobson static_assert(!__is_trivially_copyable(KindComparisonChecker2<0>));
137b1c960fcSRoy Jacobson 
138b1c960fcSRoy Jacobson static_assert(__is_trivial(KindComparisonChecker3<0>));
139b1c960fcSRoy Jacobson static_assert(__is_trivially_copyable(KindComparisonChecker3<0>));
140b1c960fcSRoy Jacobson 
141b1c960fcSRoy Jacobson template <class T>
142b1c960fcSRoy Jacobson concept HasA = requires(T t) {
143b1c960fcSRoy Jacobson     { t.a() };
144b1c960fcSRoy Jacobson };
145b1c960fcSRoy Jacobson 
146b1c960fcSRoy Jacobson template <class T>
147b1c960fcSRoy Jacobson concept HasAB = HasA<T> && requires(T t) {
148b1c960fcSRoy Jacobson     { t.b() };
149b1c960fcSRoy Jacobson };
150b1c960fcSRoy Jacobson 
151b1c960fcSRoy Jacobson template <class T>
152b1c960fcSRoy Jacobson concept HasAC = HasA<T> && requires(T t) {
153b1c960fcSRoy Jacobson     { t.c() };
154b1c960fcSRoy Jacobson };
155b1c960fcSRoy Jacobson 
156b1c960fcSRoy Jacobson template <class T>
157b1c960fcSRoy Jacobson concept HasABC = HasAB<T> && HasAC<T> && requires(T t) {
158b1c960fcSRoy Jacobson     { t.c() };
159b1c960fcSRoy Jacobson };
160b1c960fcSRoy Jacobson 
161b1c960fcSRoy Jacobson template <class T>
162b1c960fcSRoy Jacobson struct ComplexConstraints {
163b1c960fcSRoy Jacobson     ComplexConstraints() requires HasABC<T> = default;
164b1c960fcSRoy Jacobson     ComplexConstraints() requires HasAB<T>;
165b1c960fcSRoy Jacobson     ComplexConstraints() requires HasAC<T>;
166b1c960fcSRoy Jacobson     ComplexConstraints() requires HasA<T> = delete;
167b1c960fcSRoy Jacobson     ComplexConstraints();
168b1c960fcSRoy Jacobson };
169b1c960fcSRoy Jacobson 
170b1c960fcSRoy Jacobson struct A {
171b1c960fcSRoy Jacobson     void a();
172b1c960fcSRoy Jacobson };
173b1c960fcSRoy Jacobson 
174b1c960fcSRoy Jacobson struct AB {
175b1c960fcSRoy Jacobson     void a();
176b1c960fcSRoy Jacobson     void b();
177b1c960fcSRoy Jacobson };
178b1c960fcSRoy Jacobson 
179b1c960fcSRoy Jacobson struct ABC {
180b1c960fcSRoy Jacobson     void a();
181b1c960fcSRoy Jacobson     void b();
182b1c960fcSRoy Jacobson     void c();
183b1c960fcSRoy Jacobson };
184b1c960fcSRoy Jacobson 
185b1c960fcSRoy Jacobson struct AC {
186b1c960fcSRoy Jacobson     void a();
187b1c960fcSRoy Jacobson     void c();
188b1c960fcSRoy Jacobson };
189b1c960fcSRoy Jacobson 
190b1c960fcSRoy Jacobson static_assert(__is_trivial(ComplexConstraints<ABC>), "");
191b1c960fcSRoy Jacobson static_assert(!__is_trivial(ComplexConstraints<AB>), "");
192b1c960fcSRoy Jacobson static_assert(!__is_trivial(ComplexConstraints<AC>), "");
193b1c960fcSRoy Jacobson static_assert(__is_trivial(ComplexConstraints<A>), "");
194b1c960fcSRoy Jacobson static_assert(!__is_trivial(ComplexConstraints<int>), "");
195b1c960fcSRoy Jacobson 
196b1c960fcSRoy Jacobson 
197b1c960fcSRoy Jacobson // This is evaluated at the completion of CRTPBase, while `T` is not yet completed.
198b1c960fcSRoy Jacobson // This is probably correct behavior.
199b1c960fcSRoy Jacobson template <class T>
200b1c960fcSRoy Jacobson struct CRTPBase {
201babdef27SErich Keane   CRTPBase() requires (sizeof(T) > 0);
202b1c960fcSRoy Jacobson   CRTPBase() = default;
203b1c960fcSRoy Jacobson };
204b1c960fcSRoy Jacobson 
205b1c960fcSRoy Jacobson struct Child : CRTPBase<Child> { int x; };
206b1c960fcSRoy Jacobson static Child c;
207b1c960fcSRoy Jacobson 
208b1c960fcSRoy Jacobson 
209b1c960fcSRoy Jacobson namespace GH57046 {
210b1c960fcSRoy Jacobson template<unsigned N>
211b1c960fcSRoy Jacobson struct Foo {
FooGH57046::Foo212b1c960fcSRoy Jacobson   Foo() requires (N==1) {} // expected-note {{declared here}}
213b1c960fcSRoy Jacobson   Foo() requires (N==2) = default;
214b1c960fcSRoy Jacobson };
215b1c960fcSRoy Jacobson 
216b1c960fcSRoy Jacobson template <unsigned N, unsigned M>
217b1c960fcSRoy Jacobson struct S {
218b1c960fcSRoy Jacobson   Foo<M> data;
SGH57046::S219b1c960fcSRoy Jacobson   S() requires (N==1) {}
220b1c960fcSRoy Jacobson   consteval S() requires (N==2) = default; // expected-note {{non-constexpr constructor 'Foo' cannot be used in a constant expression}}
221b1c960fcSRoy Jacobson };
222b1c960fcSRoy Jacobson 
func()223b1c960fcSRoy Jacobson void func() {
224b1c960fcSRoy Jacobson   S<2, 1> s1; // expected-error {{is not a constant expression}} expected-note {{in call to 'S()'}}
225b1c960fcSRoy Jacobson   S<2, 2> s2;
226b1c960fcSRoy Jacobson }
227b1c960fcSRoy Jacobson }
2287d58c956SRoy Jacobson 
2297d58c956SRoy Jacobson namespace GH59206 {
2307d58c956SRoy Jacobson 
2317d58c956SRoy Jacobson struct A {
2327d58c956SRoy Jacobson   A() = default; //eligible, second constructor unsatisfied
2337d58c956SRoy Jacobson   template<class... Args>
AGH59206::A2347d58c956SRoy Jacobson   A(Args&&... args) requires (sizeof...(Args) > 0) {}
2357d58c956SRoy Jacobson };
2367d58c956SRoy Jacobson 
2377d58c956SRoy Jacobson struct B {
2387d58c956SRoy Jacobson   B() = default; //ineligible, second constructor more constrained
2397d58c956SRoy Jacobson   template<class... Args>
BGH59206::B2407d58c956SRoy Jacobson   B(Args&&... args) requires (sizeof...(Args) == 0) {}
2417d58c956SRoy Jacobson };
2427d58c956SRoy Jacobson 
2437d58c956SRoy Jacobson struct C {
2447d58c956SRoy Jacobson   C() = default; //eligible, but
2457d58c956SRoy Jacobson   template<class... Args> //also eligible and non-trivial
CGH59206::C2467d58c956SRoy Jacobson   C(Args&&... args) {}
2477d58c956SRoy Jacobson };
2487d58c956SRoy Jacobson 
2497d58c956SRoy Jacobson struct D : B {};
2507d58c956SRoy Jacobson 
2517d58c956SRoy Jacobson static_assert(__is_trivially_copyable(A), "");
2527d58c956SRoy Jacobson static_assert(__is_trivially_copyable(B), "");
2537d58c956SRoy Jacobson static_assert(__is_trivially_copyable(C), "");
2547d58c956SRoy Jacobson static_assert(__is_trivially_copyable(D), "");
2557d58c956SRoy Jacobson 
2567d58c956SRoy Jacobson // FIXME: Update when https://github.com/llvm/llvm-project/issues/59206 is
2577d58c956SRoy Jacobson // resolved.
2587d58c956SRoy Jacobson static_assert(!__is_trivial(A), "");
2597d58c956SRoy Jacobson static_assert(!__is_trivial(B), "");
2607d58c956SRoy Jacobson static_assert(!__is_trivial(C), "");
2617d58c956SRoy Jacobson static_assert(__is_trivial(D), "");
2627d58c956SRoy Jacobson static_assert(__is_trivially_constructible(A), "");
2637d58c956SRoy Jacobson static_assert(__is_trivially_constructible(B), "");
2647d58c956SRoy Jacobson static_assert(__is_trivially_constructible(C), "");
2657d58c956SRoy Jacobson static_assert(__is_trivially_constructible(D), "");
2667d58c956SRoy Jacobson 
2677d58c956SRoy Jacobson }
268000ec50eSRoy Jacobson 
269000ec50eSRoy Jacobson namespace GH60697 {
270000ec50eSRoy Jacobson 
271000ec50eSRoy Jacobson template <class T>
272000ec50eSRoy Jacobson struct X {
273000ec50eSRoy Jacobson     X() requires false = default;
274000ec50eSRoy Jacobson };
275000ec50eSRoy Jacobson static_assert(!__is_trivial(X<int>));
276000ec50eSRoy Jacobson 
277000ec50eSRoy Jacobson template <class T>
278000ec50eSRoy Jacobson struct S {
279000ec50eSRoy Jacobson     S() requires(__is_trivially_constructible(T)) = default;
280000ec50eSRoy Jacobson 
SGH60697::S281000ec50eSRoy Jacobson     S() requires(!__is_trivially_constructible(T) &&
282000ec50eSRoy Jacobson                   __is_constructible(T)) {}
283000ec50eSRoy Jacobson 
284000ec50eSRoy Jacobson     T t;
285000ec50eSRoy Jacobson };
286000ec50eSRoy Jacobson 
287000ec50eSRoy Jacobson struct D {
DGH60697::D288000ec50eSRoy Jacobson     D(int i) : i(i) {}
289000ec50eSRoy Jacobson     int i;
290000ec50eSRoy Jacobson };
291000ec50eSRoy Jacobson static_assert(!__is_trivially_constructible(D));
292000ec50eSRoy Jacobson static_assert(!__is_constructible(D));
293000ec50eSRoy Jacobson static_assert(!__is_trivial(D));
294000ec50eSRoy Jacobson 
295000ec50eSRoy Jacobson static_assert(!__is_trivially_constructible(S<D>));
296000ec50eSRoy Jacobson static_assert(!__is_constructible(S<D>));
297000ec50eSRoy Jacobson 
298000ec50eSRoy Jacobson static_assert(__is_trivial(S<int>));
299000ec50eSRoy Jacobson static_assert(!__is_trivial(S<D>));
300000ec50eSRoy Jacobson 
301000ec50eSRoy Jacobson }
302*0f59bee3SRoy Jacobson 
303*0f59bee3SRoy Jacobson namespace GH62555 {
304*0f59bee3SRoy Jacobson 
305*0f59bee3SRoy Jacobson template <bool B>
306*0f59bee3SRoy Jacobson struct ExplicitTemplateArgs {
307*0f59bee3SRoy Jacobson     ExplicitTemplateArgs(ExplicitTemplateArgs&&) = default;
ExplicitTemplateArgsGH62555::ExplicitTemplateArgs308*0f59bee3SRoy Jacobson     ExplicitTemplateArgs(ExplicitTemplateArgs<false>&&) requires B {};
309*0f59bee3SRoy Jacobson };
310*0f59bee3SRoy Jacobson 
311*0f59bee3SRoy Jacobson static_assert(__is_trivially_copyable(ExplicitTemplateArgs<false>));
312*0f59bee3SRoy Jacobson static_assert(__is_trivially_copyable(ExplicitTemplateArgs<true>));
313*0f59bee3SRoy Jacobson 
314*0f59bee3SRoy Jacobson }
315