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