| 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 | |