xref: /llvm-project/clang/test/CXX/special/class.copy/p11.0x.move.cpp (revision 89d9912cbf45068770ac8c1e2ef97b74c3b662ab)
19ca5c425SRichard Smith // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
277c1f9f8SAlexis Hunt 
3c91d12ceSRichard Smith struct Trivial {};
477c1f9f8SAlexis Hunt struct NonTrivial {
5566184acSRichard Smith   NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}}
677c1f9f8SAlexis Hunt };
7dd5619feSRichard Smith struct DeletedCopy {
8dd5619feSRichard Smith   DeletedCopy(const DeletedCopy&) = delete;
9dd5619feSRichard Smith };
1077c1f9f8SAlexis Hunt 
11522fa537SRichard Smith // A defaulted move constructor for a class X is defined as deleted if X has:
12522fa537SRichard Smith 
13522fa537SRichard Smith // -- a variant member with a non-trivial corresponding constructor
1477c1f9f8SAlexis Hunt union DeletedNTVariant {
15566184acSRichard Smith   NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
1677c1f9f8SAlexis Hunt   DeletedNTVariant(DeletedNTVariant&&);
1777c1f9f8SAlexis Hunt };
1877c1f9f8SAlexis Hunt DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
1977c1f9f8SAlexis Hunt 
2077c1f9f8SAlexis Hunt struct DeletedNTVariant2 {
2177c1f9f8SAlexis Hunt   union {
22566184acSRichard Smith     NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
2377c1f9f8SAlexis Hunt   };
2477c1f9f8SAlexis Hunt   DeletedNTVariant2(DeletedNTVariant2&&);
2577c1f9f8SAlexis Hunt };
2677c1f9f8SAlexis Hunt DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}}
2777c1f9f8SAlexis Hunt 
28dd5619feSRichard Smith // Note, move constructor is not a candidate because it is deleted.
29dd5619feSRichard Smith template<typename T> struct DeletedNTVariant3 { // expected-note 2{{default}} expected-note 2{{copy}}
30dd5619feSRichard Smith   union {
31dd5619feSRichard Smith     T NT;
32dd5619feSRichard Smith   };
33dd5619feSRichard Smith };
34dd5619feSRichard Smith extern DeletedNTVariant3<NonTrivial> dntv3a(0); // expected-error {{no matching}}
35*89d9912cSHaojian Wu extern DeletedNTVariant3<DeletedCopy> dntv3b(0); // expected-error {{no matching}}
36dd5619feSRichard Smith 
37522fa537SRichard Smith // -- a non-static data member of class type M (or array thereof) that cannot be
38522fa537SRichard Smith //    copied because overload resolution results in an ambiguity or a function
39522fa537SRichard Smith //    that is deleted or inaccessible
4077c1f9f8SAlexis Hunt struct NoAccess {
4177c1f9f8SAlexis Hunt   NoAccess() = default;
4277c1f9f8SAlexis Hunt private:
4377c1f9f8SAlexis Hunt   NoAccess(NoAccess&&);
4477c1f9f8SAlexis Hunt 
4577c1f9f8SAlexis Hunt   friend struct HasAccess;
4677c1f9f8SAlexis Hunt };
4777c1f9f8SAlexis Hunt 
4877c1f9f8SAlexis Hunt struct HasNoAccess {
49566184acSRichard Smith   NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}
5077c1f9f8SAlexis Hunt   HasNoAccess(HasNoAccess&&);
5177c1f9f8SAlexis Hunt };
5277c1f9f8SAlexis Hunt HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
5377c1f9f8SAlexis Hunt 
5477c1f9f8SAlexis Hunt struct HasAccess {
5577c1f9f8SAlexis Hunt   NoAccess NA;
5677c1f9f8SAlexis Hunt   HasAccess(HasAccess&&);
5777c1f9f8SAlexis Hunt };
5877c1f9f8SAlexis Hunt HasAccess::HasAccess(HasAccess&&) = default;
5977c1f9f8SAlexis Hunt 
60522fa537SRichard Smith struct Ambiguity {
61522fa537SRichard Smith   Ambiguity(const Ambiguity&&);
62522fa537SRichard Smith   Ambiguity(volatile Ambiguity&&);
63522fa537SRichard Smith };
64522fa537SRichard Smith 
65522fa537SRichard Smith struct IsAmbiguous {
66566184acSRichard Smith   Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}}
67566184acSRichard Smith   IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}}
68522fa537SRichard Smith };
69522fa537SRichard Smith IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}
70522fa537SRichard Smith 
71522fa537SRichard Smith struct Deleted {
72566184acSRichard Smith   // FIXME: This diagnostic is slightly wrong: the constructor we select to move
73566184acSRichard Smith   // 'IA' is deleted, but we select the copy constructor (we ignore the move
74566184acSRichard Smith   // constructor, because it was defaulted and deleted).
75566184acSRichard Smith   IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}}
76522fa537SRichard Smith   Deleted(Deleted&&);
77522fa537SRichard Smith };
78522fa537SRichard Smith Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}}
79522fa537SRichard Smith 
80c91d12ceSRichard Smith // It's implied (but not stated) that this should also happen if overload
81c91d12ceSRichard Smith // resolution fails.
82c91d12ceSRichard Smith struct ConstMember {
83c91d12ceSRichard Smith   const Trivial ct;
84c91d12ceSRichard Smith   ConstMember(ConstMember&&);
85c91d12ceSRichard Smith };
86c91d12ceSRichard Smith ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor
87c91d12ceSRichard Smith struct ConstMoveOnlyMember {
88566184acSRichard Smith   // FIXME: This diagnostic is slightly wrong: the constructor we select to move
89566184acSRichard Smith   // 'cnt' is deleted, but we select the copy constructor, because the object is
90566184acSRichard Smith   // const.
91566184acSRichard Smith   const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}}
92c91d12ceSRichard Smith   ConstMoveOnlyMember(ConstMoveOnlyMember&&);
93c91d12ceSRichard Smith };
94c91d12ceSRichard Smith ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}
95c91d12ceSRichard Smith struct VolatileMember {
96566184acSRichard Smith   volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}}
97c91d12ceSRichard Smith   VolatileMember(VolatileMember&&);
98c91d12ceSRichard Smith };
99c91d12ceSRichard Smith VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}}
100c91d12ceSRichard Smith 
101522fa537SRichard Smith // -- a direct or virtual base class B that cannot be moved because overload
102522fa537SRichard Smith //    resolution results in an ambiguity or a function that is deleted or
103522fa537SRichard Smith //    inaccessible
104566184acSRichard Smith struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}
105566184acSRichard Smith   AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}}
106522fa537SRichard Smith };
107522fa537SRichard Smith AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}
108522fa537SRichard Smith 
109566184acSRichard Smith struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}}
110522fa537SRichard Smith   DeletedMoveBase(DeletedMoveBase&&);
111522fa537SRichard Smith };
112522fa537SRichard Smith DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}
113522fa537SRichard Smith 
114566184acSRichard Smith struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}}
115522fa537SRichard Smith   InaccessibleMoveBase(InaccessibleMoveBase&&);
116522fa537SRichard Smith };
117522fa537SRichard Smith InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}
118522fa537SRichard Smith 
119522fa537SRichard Smith // -- any direct or virtual base class or non-static data member of a type with
120522fa537SRichard Smith //    a destructor that is deleted or inaccessible
12177c1f9f8SAlexis Hunt struct NoAccessDtor {
122852265ffSRichard Smith   NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}
12377c1f9f8SAlexis Hunt private:
12477c1f9f8SAlexis Hunt   ~NoAccessDtor();
12577c1f9f8SAlexis Hunt   friend struct HasAccessDtor;
12677c1f9f8SAlexis Hunt };
12777c1f9f8SAlexis Hunt 
12877c1f9f8SAlexis Hunt struct HasNoAccessDtor {
129566184acSRichard Smith   NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}
13077c1f9f8SAlexis Hunt   HasNoAccessDtor(HasNoAccessDtor&&);
13177c1f9f8SAlexis Hunt };
13277c1f9f8SAlexis Hunt HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}
13377c1f9f8SAlexis Hunt 
13477c1f9f8SAlexis Hunt struct HasAccessDtor {
13577c1f9f8SAlexis Hunt   NoAccessDtor NAD;
13677c1f9f8SAlexis Hunt   HasAccessDtor(HasAccessDtor&&);
13777c1f9f8SAlexis Hunt };
13877c1f9f8SAlexis Hunt HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;
13977c1f9f8SAlexis Hunt 
140852265ffSRichard Smith struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}
141522fa537SRichard Smith };
142522fa537SRichard Smith extern HasNoAccessDtorBase HNADBa;
143522fa537SRichard Smith HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
144522fa537SRichard Smith 
145522fa537SRichard Smith // The restriction on rvalue reference members applies to only the copy
146522fa537SRichard Smith // constructor.
14777c1f9f8SAlexis Hunt struct RValue {
148d87aab93SRichard Smith   int &&ri = 1;
14977c1f9f8SAlexis Hunt   RValue(RValue&&);
15077c1f9f8SAlexis Hunt };
15177c1f9f8SAlexis Hunt RValue::RValue(RValue&&) = default;
15277c1f9f8SAlexis Hunt 
153522fa537SRichard Smith // -- a non-static data member or direct or virtual base class with a type that
154522fa537SRichard Smith //    does not have a move constructor and is not trivially copyable
15577c1f9f8SAlexis Hunt struct CopyOnly {
15677c1f9f8SAlexis Hunt   CopyOnly(const CopyOnly&);
15777c1f9f8SAlexis Hunt };
15877c1f9f8SAlexis Hunt 
15977c1f9f8SAlexis Hunt struct NonMove {
16077c1f9f8SAlexis Hunt   CopyOnly CO;
16177c1f9f8SAlexis Hunt   NonMove(NonMove&&);
16277c1f9f8SAlexis Hunt };
163cf8ec8daSRichard Smith NonMove::NonMove(NonMove&&) = default; // ok under DR1402
16477c1f9f8SAlexis Hunt 
16577c1f9f8SAlexis Hunt struct Moveable {
16677c1f9f8SAlexis Hunt   Moveable();
16777c1f9f8SAlexis Hunt   Moveable(Moveable&&);
16877c1f9f8SAlexis Hunt };
16977c1f9f8SAlexis Hunt 
17077c1f9f8SAlexis Hunt struct HasMove {
17177c1f9f8SAlexis Hunt   Moveable M;
17277c1f9f8SAlexis Hunt   HasMove(HasMove&&);
17377c1f9f8SAlexis Hunt };
17477c1f9f8SAlexis Hunt HasMove::HasMove(HasMove&&) = default;
175cf8ec8daSRichard Smith 
176cf8ec8daSRichard Smith namespace DR1402 {
177cf8ec8daSRichard Smith   struct member {
178cf8ec8daSRichard Smith     member();
179cf8ec8daSRichard Smith     member(const member&);
180cf8ec8daSRichard Smith     member& operator=(const member&);
181cf8ec8daSRichard Smith     ~member();
182cf8ec8daSRichard Smith   };
183cf8ec8daSRichard Smith 
184cf8ec8daSRichard Smith   struct A {
185cf8ec8daSRichard Smith     member m_;
186cf8ec8daSRichard Smith 
187cf8ec8daSRichard Smith     A() = default;
188cf8ec8daSRichard Smith     A(const A&) = default;
189cf8ec8daSRichard Smith     A& operator=(const A&) = default;
190cf8ec8daSRichard Smith     A(A&&) = default;
191cf8ec8daSRichard Smith     A& operator=(A&&) = default;
192cf8ec8daSRichard Smith     ~A() = default;
193cf8ec8daSRichard Smith   };
194cf8ec8daSRichard Smith 
195cf8ec8daSRichard Smith   // ok, A's explicitly-defaulted move operations copy m_.
f()196cf8ec8daSRichard Smith   void f() {
197cf8ec8daSRichard Smith     A a, b(a), c(static_cast<A&&>(a));
198cf8ec8daSRichard Smith     a = b;
199cf8ec8daSRichard Smith     b = static_cast<A&&>(c);
200cf8ec8daSRichard Smith   }
201cf8ec8daSRichard Smith }
202