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