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