1 | // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-defaulted-function-deleted |
2 | |
3 | struct DefaultedDefCtor1 {}; |
4 | struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; }; |
5 | struct DeletedDefCtor { DeletedDefCtor() = delete; DeletedDefCtor(int); }; // expected-note {{explicitly marked deleted here}} |
6 | class PrivateDefCtor { PrivateDefCtor() = default; public: PrivateDefCtor(int); }; |
7 | struct DeletedDtor { ~DeletedDtor() = delete; }; // expected-note 4{{explicitly marked deleted here}} |
8 | class PrivateDtor { ~PrivateDtor() = default; }; |
9 | class Friend { |
10 | Friend() = default; ~Friend() = default; |
11 | friend struct NotDeleted6c; |
12 | friend struct NotDeleted7i; |
13 | friend struct NotDeleted7j; |
14 | friend struct NotDeleted7k; |
15 | }; |
16 | struct UserProvidedDefCtor { UserProvidedDefCtor() {} }; |
17 | int n; |
18 | |
19 | |
20 | // A defaulted default constructor for a class X is defined as deleted if: |
21 | |
22 | // - X is a union-like class that has a variant member with a non-trivial |
23 | // default constructor, |
24 | union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of 'Deleted1a' is implicitly deleted because variant field 'u' has a non-trivial default constructor}} |
25 | Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}} |
26 | union NotDeleted1a { DefaultedDefCtor1 nu; }; |
27 | NotDeleted1a nd1a; |
28 | union NotDeleted1b { DefaultedDefCtor2 nu; }; |
29 | NotDeleted1b nd1b; |
30 | |
31 | // - any non-static data member with no brace-or-equal-initializer is of |
32 | // reference type, |
33 | class Deleted2a { |
34 | Deleted2a() = default; // expected-note 4{{implicitly deleted here}} |
35 | int &a; // expected-note 4{{because field 'a' of reference type 'int &' would not be initialized}} |
36 | }; |
37 | Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}} |
38 | struct Deleted2b { |
39 | int &&b; // expected-note {{default constructor of 'Deleted2b' is implicitly deleted because field 'b' of reference type 'int &&' would not be initialized}} |
40 | }; |
41 | Deleted2b d2b; // expected-error {{deleted default constructor}} |
42 | class NotDeleted2a { int &a = n; }; |
43 | NotDeleted2a nd2a; |
44 | class NotDeleted2b { int &a = error; }; // expected-error {{undeclared identifier}} |
45 | NotDeleted2b nd2b; |
46 | class NotDeleted2c { int &&a = static_cast<int&&>(n); }; |
47 | NotDeleted2c nd2c; |
48 | // Note: this one does not have a deleted default constructor even though the |
49 | // implicit default constructor is ill-formed! |
50 | class NotDeleted2d { int &&a = 0; }; // expected-error {{reference member 'a' binds to a temporary object}} expected-note {{default member init}} |
51 | NotDeleted2d nd2d; // expected-note {{first required here}} |
52 | |
53 | // - any non-variant non-static data member of const qualified type (or array |
54 | // thereof) with no brace-or-equal-initializer does not have a user-provided |
55 | // default constructor, |
56 | class Deleted3a { const int a; }; // expected-note {{because field 'a' of const-qualified type 'const int' would not be initialized}} \ |
57 | expected-warning {{does not declare any constructor}} \ |
58 | expected-note {{will never be initialized}} |
59 | Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}} |
60 | class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1 [42]' would not be initialized}} |
61 | Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}} |
62 | class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor2' would not be initialized}} |
63 | Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}} |
64 | class NotDeleted3a { const int a = 0; }; |
65 | NotDeleted3a nd3a; |
66 | class NotDeleted3b { const DefaultedDefCtor1 a[42] = {}; }; |
67 | NotDeleted3b nd3b; |
68 | class NotDeleted3c { const DefaultedDefCtor2 a = DefaultedDefCtor2(); }; |
69 | NotDeleted3c nd3c; |
70 | union NotDeleted3d { const int a; int b; }; |
71 | NotDeleted3d nd3d; |
72 | union NotDeleted3e { const DefaultedDefCtor1 a[42]; int b; }; |
73 | NotDeleted3e nd3e; |
74 | union NotDeleted3f { const DefaultedDefCtor2 a; int b; }; |
75 | NotDeleted3f nd3f; |
76 | struct NotDeleted3g { union { const int a; int b; }; }; |
77 | NotDeleted3g nd3g; |
78 | |
79 | // - X is a union and all of its variant members are of const-qualified type (or |
80 | // array thereof), |
81 | union Deleted4a { |
82 | const int a; |
83 | const int b; |
84 | const UserProvidedDefCtor c; // expected-note {{because variant field 'c' has a non-trivial default constructor}} |
85 | }; |
86 | Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}} |
87 | union NotDeleted4a { const int a; int b; }; |
88 | NotDeleted4a nd4a; |
89 | |
90 | // - X is a non-union class and all members of any anonymous union member are of |
91 | // const-qualified type (or array thereof), |
92 | struct Deleted5a { |
93 | union { const int a; }; // expected-note {{because all data members of an anonymous union member are const-qualified}} |
94 | union { int b; }; |
95 | }; |
96 | Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}} |
97 | struct NotDeleted5a { union { const int a; int b; }; union { const int c; int d; }; }; |
98 | NotDeleted5a nd5a; |
99 | |
100 | // - any direct or virtual base class, or non-static data member with no |
101 | // brace-or-equal-initializer, has class type M (or array thereof) and either |
102 | // M has no default constructor or overload resolution as applied to M's default |
103 | // constructor results in an ambiguity or in a function that is deleted or |
104 | // inaccessible from the defaulted default constructor, or |
105 | struct Deleted6a : Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}} |
106 | Deleted6a d6a; // expected-error {{implicitly-deleted default constructor}} |
107 | struct Deleted6b : virtual Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}} |
108 | Deleted6b d6b; // expected-error {{implicitly-deleted default constructor}} |
109 | struct Deleted6c { Deleted2a a; }; // expected-note {{because field 'a' has a deleted default constructor}} |
110 | Deleted6c d6c; // expected-error {{implicitly-deleted default constructor}} |
111 | struct Deleted6d { DeletedDefCtor a; }; // expected-note {{because field 'a' has a deleted default constructor}} |
112 | Deleted6d d6d; // expected-error {{implicitly-deleted default constructor}} |
113 | struct NotDeleted6a { DeletedDefCtor a = 0; }; |
114 | NotDeleted6a nd6a; |
115 | struct Deleted6e { PrivateDefCtor a; }; // expected-note {{because field 'a' has an inaccessible default constructor}} |
116 | Deleted6e d6e; // expected-error {{implicitly-deleted default constructor}} |
117 | struct NotDeleted6b { PrivateDefCtor a = 0; }; |
118 | NotDeleted6b nd6b; |
119 | struct NotDeleted6c { Friend a; }; |
120 | NotDeleted6c nd6c; |
121 | |
122 | // - any direct or virtual base class or non-static data member has a type with |
123 | // a destructor that is deleted or inaccessible from the defaulted default |
124 | // constructor. |
125 | struct Deleted7a : DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}} |
126 | Deleted7a d7a; // expected-error {{implicitly-deleted default constructor}} |
127 | struct Deleted7b : virtual DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}} |
128 | Deleted7b d7b; // expected-error {{implicitly-deleted default constructor}} |
129 | struct Deleted7c { DeletedDtor a; }; // expected-note {{because field 'a' has a deleted destructor}} |
130 | Deleted7c d7c; // expected-error {{implicitly-deleted default constructor}} |
131 | struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{because field 'a' has a deleted destructor}} |
132 | Deleted7d d7d; // expected-error {{implicitly-deleted default constructor}} |
133 | struct Deleted7e : PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}} |
134 | Deleted7e d7e; // expected-error {{implicitly-deleted default constructor}} |
135 | struct Deleted7f : virtual PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}} |
136 | Deleted7f d7f; // expected-error {{implicitly-deleted default constructor}} |
137 | struct Deleted7g { PrivateDtor a; }; // expected-note {{field 'a' has an inaccessible destructor}} |
138 | Deleted7g d7g; // expected-error {{implicitly-deleted default constructor}} |
139 | struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{field 'a' has an inaccessible destructor}} |
140 | Deleted7h d7h; // expected-error {{implicitly-deleted default constructor}} |
141 | struct NotDeleted7i : Friend {}; |
142 | NotDeleted7i d7i; |
143 | struct NotDeleted7j : virtual Friend {}; |
144 | NotDeleted7j d7j; |
145 | struct NotDeleted7k { Friend a; }; |
146 | NotDeleted7k d7k; |
147 | |
148 | |
149 | class Trivial { static const int n = 42; }; |
150 | static_assert(__has_trivial_constructor(Trivial), "Trivial is nontrivial"); |
151 | |
152 | // A default constructor is trivial if it is not user-provided and if: |
153 | class NonTrivialDefCtor1 { NonTrivialDefCtor1(); }; |
154 | static_assert(!__has_trivial_constructor(NonTrivialDefCtor1), "NonTrivialDefCtor1 is trivial"); |
155 | |
156 | #define ASSERT_NONTRIVIAL_IMPL(Class, Bases, Body) \ |
157 | class Class Bases { Body }; \ |
158 | static_assert(!__has_trivial_constructor(Class), ""); |
159 | #define ASSERT_NONTRIVIAL(Class, Bases, Body) \ |
160 | ASSERT_NONTRIVIAL_IMPL(Class, Bases, Body) \ |
161 | ASSERT_NONTRIVIAL_IMPL(Def ## Class, Bases, Def ## Class() = default; Body) \ |
162 | ASSERT_NONTRIVIAL_IMPL(Del ## Class, Bases, Del ## Class() = delete; Body) |
163 | |
164 | // - its class has no virtual functions (10.3) and no virtual base classes (10.1), and |
165 | ASSERT_NONTRIVIAL(NonTrivialDefCtor2, , virtual void f();) |
166 | ASSERT_NONTRIVIAL(NonTrivialDefCtor3, : virtual Trivial, ) |
167 | |
168 | // - no non-static data member of its class has a brace-or-equal-initializer, and |
169 | ASSERT_NONTRIVIAL(NonTrivialDefCtor4, , int m = 52;) |
170 | |
171 | // - all the direct base classes of its class have trivial default constructors, and |
172 | ASSERT_NONTRIVIAL(NonTrivialDefCtor5, : NonTrivialDefCtor1, ) |
173 | |
174 | // - for all the non-static data members of its class that are of class type (or array thereof), each such class |
175 | // has a trivial default constructor. |
176 | ASSERT_NONTRIVIAL(NonTrivialDefCtor6, , NonTrivialDefCtor1 t;) |
177 | |
178 | // FIXME: No core issue number yet. |
179 | // - its parameter-declaration-clause is equivalent to that of an implicit declaration. |
180 | struct NonTrivialDefCtor7 { |
181 | NonTrivialDefCtor7(...) = delete; |
182 | }; |
183 | static_assert(!__has_trivial_constructor(NonTrivialDefCtor7), ""); |
184 | struct NonTrivialDefCtor8 { |
185 | NonTrivialDefCtor8(int = 0) = delete; |
186 | }; |
187 | static_assert(!__has_trivial_constructor(NonTrivialDefCtor8), ""); |
188 | |
189 | // Otherwise, the default constructor is non-trivial. |
190 | |
191 | class Trivial2 { Trivial2() = delete; }; |
192 | static_assert(__has_trivial_constructor(Trivial2), "Trivial2 is trivial"); |
193 | |
194 | class Trivial3 { Trivial3() = default; }; |
195 | static_assert(__has_trivial_constructor(Trivial3), "Trivial3 is trivial"); |
196 | |
197 | template<typename T> class Trivial4 { Trivial4() = default; }; |
198 | static_assert(__has_trivial_constructor(Trivial4<int>), "Trivial4 is trivial"); |
199 | |
200 | template<typename T> class Trivial5 { Trivial5() = delete; }; |
201 | static_assert(__has_trivial_constructor(Trivial5<int>), "Trivial5 is trivial"); |
202 | |
203 | namespace PR14558 { |
204 | // Ensure we determine whether an explicitly-defaulted or deleted special |
205 | // member is trivial before we return to parsing the containing class. |
206 | struct A { |
207 | struct B { B() = default; } b; |
208 | struct C { C() = delete; } c; |
209 | }; |
210 | |
211 | static_assert(__has_trivial_constructor(A), ""); |
212 | static_assert(__has_trivial_constructor(A::B), ""); |
213 | } |
214 | |