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_assignable_check {
6ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __has_trivial_assign(T), "");
7ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_assignable(T&, T), "");
8ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_assignable(T&, const T &), "");
9ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_assignable(T&, T &&), "");
10ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_assignable(T&&, T), "");
11ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_assignable(T&&, const T &), "");
12ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  static_assert(B == __is_trivially_assignable(T&&, T &&), "");
13ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  typedef void type;
14ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
15ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithtemplate<typename T> using trivially_assignable =
16ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  typename trivially_assignable_check<T, true>::type;
17ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithtemplate<typename T> using not_trivially_assignable =
18ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  typename trivially_assignable_check<T, false>::type;
19ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
20ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct Trivial {};
21ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = trivially_assignable<Trivial>;
22ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
23ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// A copy/move assignment operator for class X is trivial if it is not user-provided,
24ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct UserProvided {
25ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  UserProvided &operator=(const UserProvided &);
26ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
27ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = not_trivially_assignable<UserProvided>;
28ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
29ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// its declared parameter type is the same as if it had been implicitly
30ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// declared,
31ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct NonConstCopy {
32ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  NonConstCopy &operator=(NonConstCopy &) = default;
33ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
34ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = not_trivially_assignable<NonConstCopy>;
35ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
36ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// class X has no virtual functions
37ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct VFn {
38ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  virtual void f();
39ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
40ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = not_trivially_assignable<VFn>;
41ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
42ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// and no virtual base classes
43ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct VBase : virtual Trivial {};
44ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = not_trivially_assignable<VBase>;
45ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
46ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// and the assignment operator selected to copy/move each [direct subobject] is trivial
47ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct TemplateCtor {
48ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  template<typename T> TemplateCtor operator=(T &);
49ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
50ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = trivially_assignable<TemplateCtor>;
51ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct TemplateCtorMember {
52ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TemplateCtor tc;
53ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
54ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = trivially_assignable<TemplateCtorMember>;
55ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct MutableTemplateCtorMember {
56ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  mutable TemplateCtor mtc;
57ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
58bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(!__is_trivially_assignable(MutableTemplateCtorMember, const MutableTemplateCtorMember &), "");
59ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(MutableTemplateCtorMember, MutableTemplateCtorMember &&), "");
60ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
61ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// Both trivial and non-trivial special members.
62ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct TNT {
63ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT &operator=(const TNT &) = default; // trivial
64ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT &operator=(TNT &); // non-trivial
65ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
66ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT &operator=(TNT &&) = default; // trivial
67ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT &operator=(const TNT &&); // non-trivial
68ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
69ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
70ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__has_trivial_assign(TNT), "lie deliberately for gcc compatibility");
71ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(TNT, TNT), "");
72ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(TNT, TNT &), "");
73ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(TNT, const TNT &), "");
74ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(TNT, volatile TNT &), "");
75ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(TNT, TNT &&), "");
76ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(TNT, const TNT &&), "");
77ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(TNT, volatile TNT &&), "");
78ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
79ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// This has only trivial special members.
80ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct DerivedFromTNT : TNT {};
81ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
82ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__has_trivial_assign(DerivedFromTNT), "");
83ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT), "");
84ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT &), "");
85ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(DerivedFromTNT, const DerivedFromTNT &), "");
86ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(DerivedFromTNT, volatile DerivedFromTNT &), "");
87ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT &&), "");
88ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(DerivedFromTNT, const DerivedFromTNT &&), "");
89ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(DerivedFromTNT, volatile DerivedFromTNT &&), "");
90ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
91ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith// This has only trivial special members.
92ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct TNTMember {
93ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  TNT tnt;
94ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
95ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
96ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__has_trivial_assign(TNTMember), "");
97ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(TNTMember, TNTMember), "");
98ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(TNTMember, TNTMember &), "");
99ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(TNTMember, const TNTMember &), "");
100ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(TNTMember, volatile TNTMember &), "");
101ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(TNTMember, TNTMember &&), "");
102ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(TNTMember, const TNTMember &&), "");
103ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(TNTMember, volatile TNTMember &&), "");
104ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
105ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct NCCTNT : NonConstCopy, TNT {};
106ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
107ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__has_trivial_assign(NCCTNT), "");
108ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(NCCTNT, NCCTNT), "");
109ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(NCCTNT, NCCTNT &), "");
110ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(NCCTNT, const NCCTNT &), "");
111ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(NCCTNT, volatile NCCTNT &), "");
112ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(NCCTNT, NCCTNT &&), "");
113ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(NCCTNT, const NCCTNT &&), "");
114ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(NCCTNT, volatile NCCTNT &&), "");
115ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
116ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct MultipleTrivial {
117ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  // All four of these are trivial.
118ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  MultipleTrivial &operator=(const MultipleTrivial &) & = default;
119ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  MultipleTrivial &operator=(const MultipleTrivial &) && = default;
120ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  MultipleTrivial &operator=(MultipleTrivial &&) & = default;
121ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  MultipleTrivial &operator=(MultipleTrivial &&) && = default;
122ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
123ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
124ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithusing _ = trivially_assignable<MultipleTrivial>;
125ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith
126ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct RefQualifier {
127ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  RefQualifier &operator=(const RefQualifier &) & = default;
128ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  RefQualifier &operator=(const RefQualifier &) &&;
129ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  RefQualifier &operator=(RefQualifier &&) &;
130ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  RefQualifier &operator=(RefQualifier &&) && = default;
131ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
132ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstruct DerivedFromRefQualifier : RefQualifier {
133ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  // Both of these call the trivial copy operation.
134ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  DerivedFromRefQualifier &operator=(const DerivedFromRefQualifier &) & = default;
135ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  DerivedFromRefQualifier &operator=(const DerivedFromRefQualifier &) && = default;
136ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  // Both of these call the non-trivial move operation.
137ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  DerivedFromRefQualifier &operator=(DerivedFromRefQualifier &&) & = default;
138ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith  DerivedFromRefQualifier &operator=(DerivedFromRefQualifier &&) && = default;
139ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith};
140ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(DerivedFromRefQualifier&, const DerivedFromRefQualifier&), "");
141ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(__is_trivially_assignable(DerivedFromRefQualifier&&, const DerivedFromRefQualifier&), "");
142ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(DerivedFromRefQualifier&, DerivedFromRefQualifier&&), "");
143ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smithstatic_assert(!__is_trivially_assignable(DerivedFromRefQualifier&&, DerivedFromRefQualifier&&), "");
144bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
145bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstruct TemplateAssignNoMove {
146bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  TemplateAssignNoMove &operator=(const TemplateAssignNoMove &) = default;
147bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  template<typename T> TemplateAssignNoMove &operator=(T &&);
148bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith};
149bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_assignable(TemplateAssignNoMove, const TemplateAssignNoMove &), "");
150bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(!__is_trivially_assignable(TemplateAssignNoMove, TemplateAssignNoMove &&), "");
151bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
152bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstruct UseTemplateAssignNoMove {
153bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  TemplateAssignNoMove tanm;
154bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith};
155bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_assignable(UseTemplateAssignNoMove, const UseTemplateAssignNoMove &), "");
156bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(!__is_trivially_assignable(UseTemplateAssignNoMove, UseTemplateAssignNoMove &&), "");
157bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
158bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstruct TemplateAssignNoMoveSFINAE {
159bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  TemplateAssignNoMoveSFINAE &operator=(const TemplateAssignNoMoveSFINAE &) = default;
160bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  template<typename T, typename U = typename T::error> TemplateAssignNoMoveSFINAE &operator=(T &&);
161bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith};
162bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_assignable(TemplateAssignNoMoveSFINAE, const TemplateAssignNoMoveSFINAE &), "");
163bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_assignable(TemplateAssignNoMoveSFINAE, TemplateAssignNoMoveSFINAE &&), "");
164bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
165bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstruct UseTemplateAssignNoMoveSFINAE {
166bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  TemplateAssignNoMoveSFINAE tanm;
167bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith};
168bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_assignable(UseTemplateAssignNoMoveSFINAE, const UseTemplateAssignNoMoveSFINAE &), "");
169bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithstatic_assert(__is_trivially_assignable(UseTemplateAssignNoMoveSFINAE, UseTemplateAssignNoMoveSFINAE &&), "");
170bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
171bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smithnamespace TrivialityDependsOnImplicitDeletion {
172bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct PrivateMove {
173bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    PrivateMove &operator=(const PrivateMove &) = default;
174bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  private:
175bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    PrivateMove &operator=(PrivateMove &&);
176bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    friend class Access;
177bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
178bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_assignable(PrivateMove, const PrivateMove &), "");
179bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(!__is_trivially_assignable(PrivateMove, PrivateMove &&), "");
180bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
181bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct NoAccess {
182bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    PrivateMove pm;
183bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // NoAccess's move would be deleted, so is suppressed,
184bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // so moves of it use PrivateMove's copy ctor, which is trivial.
185bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
186bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_assignable(NoAccess, const NoAccess &), "");
187bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_assignable(NoAccess, NoAccess &&), "");
188bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct TopNoAccess : NoAccess {};
189bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_assignable(TopNoAccess, const TopNoAccess &), "");
190bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_assignable(TopNoAccess, TopNoAccess &&), "");
191bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith
192bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct Access {
193bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    PrivateMove pm;
194bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // NoAccess's move would *not* be deleted, so is *not* suppressed,
195bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith    // so moves of it use PrivateMove's move ctor, which is not trivial.
196bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  };
197bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_assignable(Access, const Access &), "");
198bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(!__is_trivially_assignable(Access, Access &&), "");
199bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  struct TopAccess : Access {};
200bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(__is_trivially_assignable(TopAccess, const TopAccess &), "");
201bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith  static_assert(!__is_trivially_assignable(TopAccess, TopAccess &&), "");
202bc2a35d5ff492107dab5bdb7682f0da2f4a88861Richard Smith}
203