xref: /aosp_15_r20/external/clang/test/CXX/special/class.copy/p11.0x.move.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li struct Trivial {};
4*67e74705SXin Li struct NonTrivial {
5*67e74705SXin Li   NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}}
6*67e74705SXin Li };
7*67e74705SXin Li 
8*67e74705SXin Li // A defaulted move constructor for a class X is defined as deleted if X has:
9*67e74705SXin Li 
10*67e74705SXin Li // -- a variant member with a non-trivial corresponding constructor
11*67e74705SXin Li union DeletedNTVariant {
12*67e74705SXin Li   NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
13*67e74705SXin Li   DeletedNTVariant(DeletedNTVariant&&);
14*67e74705SXin Li };
15*67e74705SXin Li DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
16*67e74705SXin Li 
17*67e74705SXin Li struct DeletedNTVariant2 {
18*67e74705SXin Li   union {
19*67e74705SXin Li     NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
20*67e74705SXin Li   };
21*67e74705SXin Li   DeletedNTVariant2(DeletedNTVariant2&&);
22*67e74705SXin Li };
23*67e74705SXin Li DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}}
24*67e74705SXin Li 
25*67e74705SXin Li // -- a non-static data member of class type M (or array thereof) that cannot be
26*67e74705SXin Li //    copied because overload resolution results in an ambiguity or a function
27*67e74705SXin Li //    that is deleted or inaccessible
28*67e74705SXin Li struct NoAccess {
29*67e74705SXin Li   NoAccess() = default;
30*67e74705SXin Li private:
31*67e74705SXin Li   NoAccess(NoAccess&&);
32*67e74705SXin Li 
33*67e74705SXin Li   friend struct HasAccess;
34*67e74705SXin Li };
35*67e74705SXin Li 
36*67e74705SXin Li struct HasNoAccess {
37*67e74705SXin Li   NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}
38*67e74705SXin Li   HasNoAccess(HasNoAccess&&);
39*67e74705SXin Li };
40*67e74705SXin Li HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
41*67e74705SXin Li 
42*67e74705SXin Li struct HasAccess {
43*67e74705SXin Li   NoAccess NA;
44*67e74705SXin Li   HasAccess(HasAccess&&);
45*67e74705SXin Li };
46*67e74705SXin Li HasAccess::HasAccess(HasAccess&&) = default;
47*67e74705SXin Li 
48*67e74705SXin Li struct Ambiguity {
49*67e74705SXin Li   Ambiguity(const Ambiguity&&);
50*67e74705SXin Li   Ambiguity(volatile Ambiguity&&);
51*67e74705SXin Li };
52*67e74705SXin Li 
53*67e74705SXin Li struct IsAmbiguous {
54*67e74705SXin Li   Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}}
55*67e74705SXin Li   IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}}
56*67e74705SXin Li };
57*67e74705SXin Li IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}
58*67e74705SXin Li 
59*67e74705SXin Li struct Deleted {
60*67e74705SXin Li   // FIXME: This diagnostic is slightly wrong: the constructor we select to move
61*67e74705SXin Li   // 'IA' is deleted, but we select the copy constructor (we ignore the move
62*67e74705SXin Li   // constructor, because it was defaulted and deleted).
63*67e74705SXin Li   IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}}
64*67e74705SXin Li   Deleted(Deleted&&);
65*67e74705SXin Li };
66*67e74705SXin Li Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}}
67*67e74705SXin Li 
68*67e74705SXin Li // It's implied (but not stated) that this should also happen if overload
69*67e74705SXin Li // resolution fails.
70*67e74705SXin Li struct ConstMember {
71*67e74705SXin Li   const Trivial ct;
72*67e74705SXin Li   ConstMember(ConstMember&&);
73*67e74705SXin Li };
74*67e74705SXin Li ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor
75*67e74705SXin Li struct ConstMoveOnlyMember {
76*67e74705SXin Li   // FIXME: This diagnostic is slightly wrong: the constructor we select to move
77*67e74705SXin Li   // 'cnt' is deleted, but we select the copy constructor, because the object is
78*67e74705SXin Li   // const.
79*67e74705SXin Li   const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}}
80*67e74705SXin Li   ConstMoveOnlyMember(ConstMoveOnlyMember&&);
81*67e74705SXin Li };
82*67e74705SXin Li ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}
83*67e74705SXin Li struct VolatileMember {
84*67e74705SXin Li   volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}}
85*67e74705SXin Li   VolatileMember(VolatileMember&&);
86*67e74705SXin Li };
87*67e74705SXin Li VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}}
88*67e74705SXin Li 
89*67e74705SXin Li // -- a direct or virtual base class B that cannot be moved because overload
90*67e74705SXin Li //    resolution results in an ambiguity or a function that is deleted or
91*67e74705SXin Li //    inaccessible
92*67e74705SXin Li struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}
93*67e74705SXin Li   AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}}
94*67e74705SXin Li };
95*67e74705SXin Li AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}
96*67e74705SXin Li 
97*67e74705SXin Li struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}}
98*67e74705SXin Li   DeletedMoveBase(DeletedMoveBase&&);
99*67e74705SXin Li };
100*67e74705SXin Li DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}
101*67e74705SXin Li 
102*67e74705SXin Li struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}}
103*67e74705SXin Li   InaccessibleMoveBase(InaccessibleMoveBase&&);
104*67e74705SXin Li };
105*67e74705SXin Li InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}
106*67e74705SXin Li 
107*67e74705SXin Li // -- any direct or virtual base class or non-static data member of a type with
108*67e74705SXin Li //    a destructor that is deleted or inaccessible
109*67e74705SXin Li struct NoAccessDtor {
110*67e74705SXin Li   NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}
111*67e74705SXin Li private:
112*67e74705SXin Li   ~NoAccessDtor();
113*67e74705SXin Li   friend struct HasAccessDtor;
114*67e74705SXin Li };
115*67e74705SXin Li 
116*67e74705SXin Li struct HasNoAccessDtor {
117*67e74705SXin Li   NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}
118*67e74705SXin Li   HasNoAccessDtor(HasNoAccessDtor&&);
119*67e74705SXin Li };
120*67e74705SXin Li HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}
121*67e74705SXin Li 
122*67e74705SXin Li struct HasAccessDtor {
123*67e74705SXin Li   NoAccessDtor NAD;
124*67e74705SXin Li   HasAccessDtor(HasAccessDtor&&);
125*67e74705SXin Li };
126*67e74705SXin Li HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;
127*67e74705SXin Li 
128*67e74705SXin Li struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}
129*67e74705SXin Li };
130*67e74705SXin Li extern HasNoAccessDtorBase HNADBa;
131*67e74705SXin Li HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
132*67e74705SXin Li 
133*67e74705SXin Li // The restriction on rvalue reference members applies to only the copy
134*67e74705SXin Li // constructor.
135*67e74705SXin Li struct RValue {
136*67e74705SXin Li   int &&ri = 1; // expected-warning {{binding reference member 'ri' to a temporary}} expected-note {{here}}
137*67e74705SXin Li   RValue(RValue&&);
138*67e74705SXin Li };
139*67e74705SXin Li RValue::RValue(RValue&&) = default;
140*67e74705SXin Li 
141*67e74705SXin Li // -- a non-static data member or direct or virtual base class with a type that
142*67e74705SXin Li //    does not have a move constructor and is not trivially copyable
143*67e74705SXin Li struct CopyOnly {
144*67e74705SXin Li   CopyOnly(const CopyOnly&);
145*67e74705SXin Li };
146*67e74705SXin Li 
147*67e74705SXin Li struct NonMove {
148*67e74705SXin Li   CopyOnly CO;
149*67e74705SXin Li   NonMove(NonMove&&);
150*67e74705SXin Li };
151*67e74705SXin Li NonMove::NonMove(NonMove&&) = default; // ok under DR1402
152*67e74705SXin Li 
153*67e74705SXin Li struct Moveable {
154*67e74705SXin Li   Moveable();
155*67e74705SXin Li   Moveable(Moveable&&);
156*67e74705SXin Li };
157*67e74705SXin Li 
158*67e74705SXin Li struct HasMove {
159*67e74705SXin Li   Moveable M;
160*67e74705SXin Li   HasMove(HasMove&&);
161*67e74705SXin Li };
162*67e74705SXin Li HasMove::HasMove(HasMove&&) = default;
163*67e74705SXin Li 
164*67e74705SXin Li namespace DR1402 {
165*67e74705SXin Li   struct member {
166*67e74705SXin Li     member();
167*67e74705SXin Li     member(const member&);
168*67e74705SXin Li     member& operator=(const member&);
169*67e74705SXin Li     ~member();
170*67e74705SXin Li   };
171*67e74705SXin Li 
172*67e74705SXin Li   struct A {
173*67e74705SXin Li     member m_;
174*67e74705SXin Li 
175*67e74705SXin Li     A() = default;
176*67e74705SXin Li     A(const A&) = default;
177*67e74705SXin Li     A& operator=(const A&) = default;
178*67e74705SXin Li     A(A&&) = default;
179*67e74705SXin Li     A& operator=(A&&) = default;
180*67e74705SXin Li     ~A() = default;
181*67e74705SXin Li   };
182*67e74705SXin Li 
183*67e74705SXin Li   // ok, A's explicitly-defaulted move operations copy m_.
f()184*67e74705SXin Li   void f() {
185*67e74705SXin Li     A a, b(a), c(static_cast<A&&>(a));
186*67e74705SXin Li     a = b;
187*67e74705SXin Li     b = static_cast<A&&>(c);
188*67e74705SXin Li   }
189*67e74705SXin Li }
190