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