1 // RUN: %clang_cc1 -std=c++11 -verify %s -Wno-defaulted-function-deleted
3 // expected-no-diagnostics
5 template<typename T
, bool B
> struct trivially_copyable_check
{
6 static_assert(B
== __has_trivial_copy(T
), "");
7 static_assert(B
== __is_trivially_constructible(T
, T
), "");
8 static_assert(B
== __is_trivially_constructible(T
, const T
&), "");
9 static_assert(B
== __is_trivially_constructible(T
, T
&&), "");
12 template<typename T
> using trivially_copyable
=
13 typename trivially_copyable_check
<T
, true>::type
;
14 template<typename T
> using not_trivially_copyable
=
15 typename trivially_copyable_check
<T
, false>::type
;
18 using _
= trivially_copyable
<Trivial
>;
20 // A copy/move constructor for class X is trivial if it is not user-provided,
22 UserProvided(const UserProvided
&);
24 using _
= not_trivially_copyable
<UserProvided
>;
26 // its declared parameter type is the same as if it had been implicitly
29 NonConstCopy(NonConstCopy
&) = default;
31 using _
= not_trivially_copyable
<NonConstCopy
>;
33 // class X has no virtual functions
37 using _
= not_trivially_copyable
<VFn
>;
39 // and no virtual base classes
40 struct VBase
: virtual Trivial
{};
41 using _
= not_trivially_copyable
<VBase
>;
43 // and the constructor selected to copy/move each [direct subobject] is trivial
45 template<typename T
> TemplateCtor(T
&);
47 using _
= trivially_copyable
<TemplateCtor
>;
48 struct TemplateCtorMember
{
51 using _
= trivially_copyable
<TemplateCtorMember
>;
53 // We can select a non-trivial copy ctor even if there is a trivial one.
54 struct MutableTemplateCtorMember
{
55 mutable TemplateCtor mtc
;
57 static_assert(!__is_trivially_constructible(MutableTemplateCtorMember
, const MutableTemplateCtorMember
&), "");
58 static_assert(__is_trivially_constructible(MutableTemplateCtorMember
, MutableTemplateCtorMember
&&), "");
59 struct MutableTemplateCtorMember2
{
60 MutableTemplateCtorMember2(const MutableTemplateCtorMember2
&) = default;
61 MutableTemplateCtorMember2(MutableTemplateCtorMember2
&&) = default;
62 mutable TemplateCtor mtc
;
64 static_assert(!__is_trivially_constructible(MutableTemplateCtorMember2
, const MutableTemplateCtorMember2
&), "");
65 static_assert(__is_trivially_constructible(MutableTemplateCtorMember2
, MutableTemplateCtorMember2
&&), "");
67 // Both trivial and non-trivial special members.
69 TNT(const TNT
&) = default; // trivial
70 TNT(TNT
&); // non-trivial
72 TNT(TNT
&&) = default; // trivial
73 TNT(const TNT
&&); // non-trivial
76 static_assert(!__has_trivial_copy(TNT
), "lie deliberately for gcc compatibility");
77 static_assert(__is_trivially_constructible(TNT
, TNT
), "");
78 static_assert(!__is_trivially_constructible(TNT
, TNT
&), "");
79 static_assert(__is_trivially_constructible(TNT
, const TNT
&), "");
80 static_assert(!__is_trivially_constructible(TNT
, volatile TNT
&), "");
81 static_assert(__is_trivially_constructible(TNT
, TNT
&&), "");
82 static_assert(!__is_trivially_constructible(TNT
, const TNT
&&), "");
83 static_assert(!__is_trivially_constructible(TNT
, volatile TNT
&&), "");
85 // This has only trivial special members.
86 struct DerivedFromTNT
: TNT
{};
88 static_assert(__has_trivial_copy(DerivedFromTNT
), "");
89 static_assert(__is_trivially_constructible(DerivedFromTNT
, DerivedFromTNT
), "");
90 static_assert(__is_trivially_constructible(DerivedFromTNT
, DerivedFromTNT
&), "");
91 static_assert(__is_trivially_constructible(DerivedFromTNT
, const DerivedFromTNT
&), "");
92 static_assert(!__is_trivially_constructible(DerivedFromTNT
, volatile DerivedFromTNT
&), "");
93 static_assert(__is_trivially_constructible(DerivedFromTNT
, DerivedFromTNT
&&), "");
94 static_assert(__is_trivially_constructible(DerivedFromTNT
, const DerivedFromTNT
&&), "");
95 static_assert(!__is_trivially_constructible(DerivedFromTNT
, volatile DerivedFromTNT
&&), "");
97 // This has only trivial special members.
102 static_assert(__has_trivial_copy(TNTMember
), "");
103 static_assert(__is_trivially_constructible(TNTMember
, TNTMember
), "");
104 static_assert(__is_trivially_constructible(TNTMember
, TNTMember
&), "");
105 static_assert(__is_trivially_constructible(TNTMember
, const TNTMember
&), "");
106 static_assert(!__is_trivially_constructible(TNTMember
, volatile TNTMember
&), "");
107 static_assert(__is_trivially_constructible(TNTMember
, TNTMember
&&), "");
108 static_assert(__is_trivially_constructible(TNTMember
, const TNTMember
&&), "");
109 static_assert(!__is_trivially_constructible(TNTMember
, volatile TNTMember
&&), "");
111 struct NCCTNT
: NonConstCopy
, TNT
{};
113 static_assert(!__has_trivial_copy(NCCTNT
), "");
114 static_assert(!__is_trivially_constructible(NCCTNT
, NCCTNT
), "");
115 static_assert(!__is_trivially_constructible(NCCTNT
, NCCTNT
&), "");
116 static_assert(!__is_trivially_constructible(NCCTNT
, const NCCTNT
&), "");
117 static_assert(!__is_trivially_constructible(NCCTNT
, volatile NCCTNT
&), "");
118 static_assert(!__is_trivially_constructible(NCCTNT
, NCCTNT
&&), "");
119 static_assert(!__is_trivially_constructible(NCCTNT
, const NCCTNT
&&), "");
120 static_assert(!__is_trivially_constructible(NCCTNT
, volatile NCCTNT
&&), "");
122 struct TemplateCtorNoMove
{
123 TemplateCtorNoMove(const TemplateCtorNoMove
&) = default;
124 template<typename T
> TemplateCtorNoMove(T
&&);
126 static_assert(__is_trivially_constructible(TemplateCtorNoMove
, const TemplateCtorNoMove
&), "");
127 static_assert(!__is_trivially_constructible(TemplateCtorNoMove
, TemplateCtorNoMove
&&), "");
129 struct UseTemplateCtorNoMove
{
130 TemplateCtorNoMove tcnm
;
132 static_assert(__is_trivially_constructible(UseTemplateCtorNoMove
, const UseTemplateCtorNoMove
&), "");
133 static_assert(!__is_trivially_constructible(UseTemplateCtorNoMove
, UseTemplateCtorNoMove
&&), "");
135 struct TemplateCtorNoMoveSFINAE
{
136 TemplateCtorNoMoveSFINAE(const TemplateCtorNoMoveSFINAE
&) = default;
137 template<typename T
, typename U
= typename
T::error
> TemplateCtorNoMoveSFINAE(T
&&);
139 static_assert(__is_trivially_constructible(TemplateCtorNoMoveSFINAE
, const TemplateCtorNoMoveSFINAE
&), "");
140 static_assert(__is_trivially_constructible(TemplateCtorNoMoveSFINAE
, TemplateCtorNoMoveSFINAE
&&), "");
142 struct UseTemplateCtorNoMoveSFINAE
{
143 TemplateCtorNoMoveSFINAE tcnm
;
145 static_assert(__is_trivially_constructible(UseTemplateCtorNoMoveSFINAE
, const UseTemplateCtorNoMoveSFINAE
&), "");
146 static_assert(__is_trivially_constructible(UseTemplateCtorNoMoveSFINAE
, UseTemplateCtorNoMoveSFINAE
&&), "");
148 namespace TrivialityDependsOnImplicitDeletion
{
150 PrivateMove(const PrivateMove
&) = default;
152 PrivateMove(PrivateMove
&&);
155 static_assert(__is_trivially_constructible(PrivateMove
, const PrivateMove
&), "");
156 static_assert(!__is_trivially_constructible(PrivateMove
, PrivateMove
&&), "");
160 // NoAccess's move is deleted, so moves of it use PrivateMove's copy ctor,
163 static_assert(__is_trivially_constructible(NoAccess
, const NoAccess
&), "");
164 static_assert(__is_trivially_constructible(NoAccess
, NoAccess
&&), "");
165 struct TopNoAccess
: NoAccess
{};
166 static_assert(__is_trivially_constructible(TopNoAccess
, const TopNoAccess
&), "");
167 static_assert(__is_trivially_constructible(TopNoAccess
, TopNoAccess
&&), "");
171 // NoAccess's move would *not* be deleted, so is *not* suppressed,
172 // so moves of it use PrivateMove's move ctor, which is not trivial.
174 static_assert(__is_trivially_constructible(Access
, const Access
&), "");
175 static_assert(!__is_trivially_constructible(Access
, Access
&&), "");
176 struct TopAccess
: Access
{};
177 static_assert(__is_trivially_constructible(TopAccess
, const TopAccess
&), "");
178 static_assert(!__is_trivially_constructible(TopAccess
, TopAccess
&&), "");
181 namespace TrivialityDependsOnDestructor
{
182 class HasInaccessibleDestructor
{ ~HasInaccessibleDestructor() = default; };
183 struct HasImplicitlyDeletedDestructor
: HasInaccessibleDestructor
{};
184 struct HasImplicitlyDeletedCopyCtor
: HasImplicitlyDeletedDestructor
{
185 HasImplicitlyDeletedCopyCtor() = default;
186 template<typename T
> HasImplicitlyDeletedCopyCtor(T
&&);
187 // Copy ctor is deleted but trivial.
188 // Move ctor is suppressed.
189 HasImplicitlyDeletedCopyCtor(const HasImplicitlyDeletedCopyCtor
&) = default;
190 HasImplicitlyDeletedCopyCtor(HasImplicitlyDeletedCopyCtor
&&) = default;
192 struct Test
: HasImplicitlyDeletedCopyCtor
{
193 Test(const Test
&) = default;
194 Test(Test
&&) = default;
196 // Implicit copy ctor calls deleted trivial copy ctor.
197 static_assert(__has_trivial_copy(Test
), "");
198 // This is false because the destructor is deleted.
199 static_assert(!__is_trivially_constructible(Test
, const Test
&), "");
200 // Implicit move ctor calls template ctor.
201 static_assert(!__is_trivially_constructible(Test
, Test
&&), "");
203 struct HasAccessibleDestructor
{ ~HasAccessibleDestructor() = default; };
204 struct HasImplicitlyDefaultedDestructor
: HasAccessibleDestructor
{};
205 struct HasImplicitlyDefaultedCopyCtor
: HasImplicitlyDefaultedDestructor
{
206 template<typename T
> HasImplicitlyDefaultedCopyCtor(T
&&);
207 // Copy ctor is trivial.
208 // Move ctor is trivial.
210 struct Test2
: HasImplicitlyDefaultedCopyCtor
{};
211 // Implicit copy ctor calls trivial copy ctor.
212 static_assert(__has_trivial_copy(Test2
), "");
213 static_assert(__is_trivially_constructible(Test2
, const Test2
&), "");
214 // Implicit move ctor calls trivial move ctor.
215 static_assert(__is_trivially_constructible(Test2
, Test2
&&), "");