1ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// RUN: %clang_cc1 -std=c++11 -verify %s
2ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
3bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith// expected-no-diagnostics
4bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
5ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithtemplate<typename T, bool B> struct trivially_copyable_check {
6ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __has_trivial_copy(T), "");
7ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_constructible(T, T), "");
8ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_constructible(T, const T &), "");
9ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_constructible(T, T &&), "");
10ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  typedef void type;
11ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
12ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithtemplate<typename T> using trivially_copyable =
13ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  typename trivially_copyable_check<T, true>::type;
14ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithtemplate<typename T> using not_trivially_copyable =
15ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  typename trivially_copyable_check<T, false>::type;
16ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
17ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct Trivial {};
18ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = trivially_copyable<Trivial>;
19ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
20ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// A copy/move constructor for class X is trivial if it is not user-provided,
21ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct UserProvided {
22ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  UserProvided(const UserProvided &);
23ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
24ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = not_trivially_copyable<UserProvided>;
25ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
26ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// its declared parameter type is the same as if it had been implicitly
27ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// declared,
28ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct NonConstCopy {
29ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  NonConstCopy(NonConstCopy &) = default;
30ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
31ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = not_trivially_copyable<NonConstCopy>;
32ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
33ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// class X has no virtual functions
34ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct VFn {
35ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  virtual void f();
36ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
37ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = not_trivially_copyable<VFn>;
38ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
39ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// and no virtual base classes
40ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct VBase : virtual Trivial {};
41ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = not_trivially_copyable<VBase>;
42ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
43ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// and the constructor selected to copy/move each [direct subobject] is trivial
44ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct TemplateCtor {
45ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  template<typename T> TemplateCtor(T &);
46ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
47ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = trivially_copyable<TemplateCtor>;
48ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct TemplateCtorMember {
49ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TemplateCtor tc;
50ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
51ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = trivially_copyable<TemplateCtorMember>;
52ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
53ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// We can select a non-trivial copy ctor even if there is a trivial one.
54ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct MutableTemplateCtorMember {
55ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  mutable TemplateCtor mtc;
56ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
57bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(!__is_trivially_constructible(MutableTemplateCtorMember, const MutableTemplateCtorMember &), "");
58ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(MutableTemplateCtorMember, MutableTemplateCtorMember &&), "");
59ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct MutableTemplateCtorMember2 {
60ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  MutableTemplateCtorMember2(const MutableTemplateCtorMember2 &) = default;
61ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  MutableTemplateCtorMember2(MutableTemplateCtorMember2 &&) = default;
62ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  mutable TemplateCtor mtc;
63ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
64ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(MutableTemplateCtorMember2, const MutableTemplateCtorMember2 &), "");
65ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(MutableTemplateCtorMember2, MutableTemplateCtorMember2 &&), "");
66ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
67ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// Both trivial and non-trivial special members.
68ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct TNT {
69ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT(const TNT &) = default; // trivial
70ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT(TNT &); // non-trivial
71ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
72ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT(TNT &&) = default; // trivial
73ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT(const TNT &&); // non-trivial
74ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
75ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
76ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__has_trivial_copy(TNT), "lie deliberately for gcc compatibility");
77ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(TNT, TNT), "");
78ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(TNT, TNT &), "");
79ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(TNT, const TNT &), "");
80ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(TNT, volatile TNT &), "");
81ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(TNT, TNT &&), "");
82ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(TNT, const TNT &&), "");
83ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(TNT, volatile TNT &&), "");
84ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
85ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// This has only trivial special members.
86ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct DerivedFromTNT : TNT {};
87ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
88ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__has_trivial_copy(DerivedFromTNT), "");
89ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT), "");
90ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT &), "");
91ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(DerivedFromTNT, const DerivedFromTNT &), "");
92ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(DerivedFromTNT, volatile DerivedFromTNT &), "");
93ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT &&), "");
94ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(DerivedFromTNT, const DerivedFromTNT &&), "");
95ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(DerivedFromTNT, volatile DerivedFromTNT &&), "");
96ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
97ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// This has only trivial special members.
98ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct TNTMember {
99ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT tnt;
100ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
101ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
102ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__has_trivial_copy(TNTMember), "");
103ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(TNTMember, TNTMember), "");
104ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(TNTMember, TNTMember &), "");
105ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(TNTMember, const TNTMember &), "");
106ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(TNTMember, volatile TNTMember &), "");
107ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(TNTMember, TNTMember &&), "");
108ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_constructible(TNTMember, const TNTMember &&), "");
109ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(TNTMember, volatile TNTMember &&), "");
110ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
111ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct NCCTNT : NonConstCopy, TNT {};
112ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
113ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__has_trivial_copy(NCCTNT), "");
114ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(NCCTNT, NCCTNT), "");
115ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(NCCTNT, NCCTNT &), "");
116ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(NCCTNT, const NCCTNT &), "");
117ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(NCCTNT, volatile NCCTNT &), "");
118ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(NCCTNT, NCCTNT &&), "");
119ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(NCCTNT, const NCCTNT &&), "");
120ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_constructible(NCCTNT, volatile NCCTNT &&), "");
121bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
122bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstruct TemplateCtorNoMove {
123bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  TemplateCtorNoMove(const TemplateCtorNoMove &) = default;
124bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  template<typename T> TemplateCtorNoMove(T &&);
125bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith};
126bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_constructible(TemplateCtorNoMove, const TemplateCtorNoMove &), "");
127bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(!__is_trivially_constructible(TemplateCtorNoMove, TemplateCtorNoMove &&), "");
128bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
129bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstruct UseTemplateCtorNoMove {
130bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  TemplateCtorNoMove tcnm;
131bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith};
132bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_constructible(UseTemplateCtorNoMove, const UseTemplateCtorNoMove &), "");
133bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(!__is_trivially_constructible(UseTemplateCtorNoMove, UseTemplateCtorNoMove &&), "");
134bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
135bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstruct TemplateCtorNoMoveSFINAE {
136bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  TemplateCtorNoMoveSFINAE(const TemplateCtorNoMoveSFINAE &) = default;
137bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  template<typename T, typename U = typename T::error> TemplateCtorNoMoveSFINAE(T &&);
138bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith};
139bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_constructible(TemplateCtorNoMoveSFINAE, const TemplateCtorNoMoveSFINAE &), "");
140bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_constructible(TemplateCtorNoMoveSFINAE, TemplateCtorNoMoveSFINAE &&), "");
141bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
142bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstruct UseTemplateCtorNoMoveSFINAE {
143bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  TemplateCtorNoMoveSFINAE tcnm;
144bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith};
145bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_constructible(UseTemplateCtorNoMoveSFINAE, const UseTemplateCtorNoMoveSFINAE &), "");
146bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_constructible(UseTemplateCtorNoMoveSFINAE, UseTemplateCtorNoMoveSFINAE &&), "");
147bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
148bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithnamespace TrivialityDependsOnImplicitDeletion {
149bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct PrivateMove {
150bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    PrivateMove(const PrivateMove &) = default;
151bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  private:
152bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    PrivateMove(PrivateMove &&);
153bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    friend class Access;
154bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
155bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(PrivateMove, const PrivateMove &), "");
156bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(!__is_trivially_constructible(PrivateMove, PrivateMove &&), "");
157bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
158bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct NoAccess {
159bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    PrivateMove pm;
160743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    // NoAccess's move is deleted, so moves of it use PrivateMove's copy ctor,
161743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    // which is trivial.
162bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
163bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(NoAccess, const NoAccess &), "");
164bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(NoAccess, NoAccess &&), "");
165bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct TopNoAccess : NoAccess {};
166bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(TopNoAccess, const TopNoAccess &), "");
167bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(TopNoAccess, TopNoAccess &&), "");
168bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
169bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct Access {
170bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    PrivateMove pm;
171bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // NoAccess's move would *not* be deleted, so is *not* suppressed,
172bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // so moves of it use PrivateMove's move ctor, which is not trivial.
173bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
174bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(Access, const Access &), "");
175bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(!__is_trivially_constructible(Access, Access &&), "");
176bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct TopAccess : Access {};
177bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(TopAccess, const TopAccess &), "");
178bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(!__is_trivially_constructible(TopAccess, TopAccess &&), "");
179bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith}
180bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
181bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithnamespace TrivialityDependsOnDestructor {
182bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  class HasInaccessibleDestructor { ~HasInaccessibleDestructor() = default; };
183bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct HasImplicitlyDeletedDestructor : HasInaccessibleDestructor {};
184bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct HasImplicitlyDeletedCopyCtor : HasImplicitlyDeletedDestructor {
185bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    HasImplicitlyDeletedCopyCtor() = default;
186bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    template<typename T> HasImplicitlyDeletedCopyCtor(T &&);
187bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // Copy ctor is deleted but trivial.
188bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // Move ctor is suppressed.
189bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    HasImplicitlyDeletedCopyCtor(const HasImplicitlyDeletedCopyCtor&) = default;
190bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    HasImplicitlyDeletedCopyCtor(HasImplicitlyDeletedCopyCtor&&) = default;
191bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
192bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct Test : HasImplicitlyDeletedCopyCtor {
193bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    Test(const Test&) = default;
194bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    Test(Test&&) = default;
195bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
196bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  // Implicit copy ctor calls deleted trivial copy ctor.
197bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__has_trivial_copy(Test), "");
198bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  // This is false because the destructor is deleted.
199bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(!__is_trivially_constructible(Test, const Test &), "");
200bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  // Implicit move ctor calls template ctor.
201bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(!__is_trivially_constructible(Test, Test &&), "");
202bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
203bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct HasAccessibleDestructor { ~HasAccessibleDestructor() = default; };
204bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct HasImplicitlyDefaultedDestructor : HasAccessibleDestructor {};
205bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct HasImplicitlyDefaultedCopyCtor : HasImplicitlyDefaultedDestructor {
206bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    template<typename T> HasImplicitlyDefaultedCopyCtor(T &&);
207bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // Copy ctor is trivial.
208bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // Move ctor is trivial.
209bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
210bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct Test2 : HasImplicitlyDefaultedCopyCtor {};
211bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  // Implicit copy ctor calls trivial copy ctor.
212bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__has_trivial_copy(Test2), "");
213bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(Test2, const Test2 &), "");
214bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  // Implicit move ctor calls trivial move ctor.
215bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_constructible(Test2, Test2 &&), "");
216bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith}
217