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