p11.0x.move.cpp revision 651f13cea278ec967336033dd032faef0e9fc2ec
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2
3struct Trivial {};
4struct 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
11union DeletedNTVariant {
12  NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
13  DeletedNTVariant(DeletedNTVariant&&);
14};
15DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
16
17struct DeletedNTVariant2 {
18  union {
19    NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
20  };
21  DeletedNTVariant2(DeletedNTVariant2&&);
22};
23DeletedNTVariant2::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
28struct NoAccess {
29  NoAccess() = default;
30private:
31  NoAccess(NoAccess&&);
32
33  friend struct HasAccess;
34};
35
36struct HasNoAccess {
37  NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}
38  HasNoAccess(HasNoAccess&&);
39};
40HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
41
42struct HasAccess {
43  NoAccess NA;
44  HasAccess(HasAccess&&);
45};
46HasAccess::HasAccess(HasAccess&&) = default;
47
48struct Ambiguity {
49  Ambiguity(const Ambiguity&&);
50  Ambiguity(volatile Ambiguity&&);
51};
52
53struct 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};
57IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}
58
59struct 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};
66Deleted::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.
70struct ConstMember {
71  const Trivial ct;
72  ConstMember(ConstMember&&);
73};
74ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor
75struct 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};
82ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}
83struct VolatileMember {
84  volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}}
85  VolatileMember(VolatileMember&&);
86};
87VolatileMember::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
92struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}
93  AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}}
94};
95AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}
96
97struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}}
98  DeletedMoveBase(DeletedMoveBase&&);
99};
100DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}
101
102struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}}
103  InaccessibleMoveBase(InaccessibleMoveBase&&);
104};
105InaccessibleMoveBase::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
109struct NoAccessDtor {
110  NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}
111private:
112  ~NoAccessDtor();
113  friend struct HasAccessDtor;
114};
115
116struct HasNoAccessDtor {
117  NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}
118  HasNoAccessDtor(HasNoAccessDtor&&);
119};
120HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}
121
122struct HasAccessDtor {
123  NoAccessDtor NAD;
124  HasAccessDtor(HasAccessDtor&&);
125};
126HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;
127
128struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}
129};
130extern HasNoAccessDtorBase HNADBa;
131HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
132
133// The restriction on rvalue reference members applies to only the copy
134// constructor.
135struct RValue {
136  int &&ri = 1; // expected-warning {{binding reference member 'ri' to a temporary}} expected-note {{here}}
137  RValue(RValue&&);
138};
139RValue::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
143struct CopyOnly {
144  CopyOnly(const CopyOnly&);
145};
146
147struct NonMove {
148  CopyOnly CO;
149  NonMove(NonMove&&);
150};
151NonMove::NonMove(NonMove&&) = default; // ok under DR1402
152
153struct Moveable {
154  Moveable();
155  Moveable(Moveable&&);
156};
157
158struct HasMove {
159  Moveable M;
160  HasMove(HasMove&&);
161};
162HasMove::HasMove(HasMove&&) = default;
163
164namespace 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_.
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