// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s struct Trivial {}; struct NonTrivial { NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}} }; // A defaulted move constructor for a class X is defined as deleted if X has: // -- a variant member with a non-trivial corresponding constructor union DeletedNTVariant { NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}} DeletedNTVariant(DeletedNTVariant&&); }; DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}} struct DeletedNTVariant2 { union { NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}} }; DeletedNTVariant2(DeletedNTVariant2&&); }; DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}} // -- a non-static data member of class type M (or array thereof) that cannot be // copied because overload resolution results in an ambiguity or a function // that is deleted or inaccessible struct NoAccess { NoAccess() = default; private: NoAccess(NoAccess&&); friend struct HasAccess; }; struct HasNoAccess { NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}} HasNoAccess(HasNoAccess&&); }; HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}} struct HasAccess { NoAccess NA; HasAccess(HasAccess&&); }; HasAccess::HasAccess(HasAccess&&) = default; struct Ambiguity { Ambiguity(const Ambiguity&&); Ambiguity(volatile Ambiguity&&); }; struct IsAmbiguous { Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}} IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}} }; IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}} struct Deleted { // FIXME: This diagnostic is slightly wrong: the constructor we select to move // 'IA' is deleted, but we select the copy constructor (we ignore the move // constructor, because it was defaulted and deleted). IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}} Deleted(Deleted&&); }; Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}} // It's implied (but not stated) that this should also happen if overload // resolution fails. struct ConstMember { const Trivial ct; ConstMember(ConstMember&&); }; ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor struct ConstMoveOnlyMember { // FIXME: This diagnostic is slightly wrong: the constructor we select to move // 'cnt' is deleted, but we select the copy constructor, because the object is // const. const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}} ConstMoveOnlyMember(ConstMoveOnlyMember&&); }; ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}} struct VolatileMember { volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}} VolatileMember(VolatileMember&&); }; VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}} // -- a direct or virtual base class B that cannot be moved because overload // resolution results in an ambiguity or a function that is deleted or // inaccessible struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}} AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}} }; AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}} struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}} DeletedMoveBase(DeletedMoveBase&&); }; DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}} struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}} InaccessibleMoveBase(InaccessibleMoveBase&&); }; InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}} // -- any direct or virtual base class or non-static data member of a type with // a destructor that is deleted or inaccessible struct NoAccessDtor { NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}} private: ~NoAccessDtor(); friend struct HasAccessDtor; }; struct HasNoAccessDtor { NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}} HasNoAccessDtor(HasNoAccessDtor&&); }; HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}} struct HasAccessDtor { NoAccessDtor NAD; HasAccessDtor(HasAccessDtor&&); }; HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default; struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}} }; extern HasNoAccessDtorBase HNADBa; HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}} // The restriction on rvalue reference members applies to only the copy // constructor. struct RValue { int &&ri = 1; // expected-warning {{binding reference member 'ri' to a temporary}} expected-note {{here}} RValue(RValue&&); }; RValue::RValue(RValue&&) = default; // -- a non-static data member or direct or virtual base class with a type that // does not have a move constructor and is not trivially copyable struct CopyOnly { CopyOnly(const CopyOnly&); }; struct NonMove { CopyOnly CO; NonMove(NonMove&&); }; NonMove::NonMove(NonMove&&) = default; // ok under DR1402 struct Moveable { Moveable(); Moveable(Moveable&&); }; struct HasMove { Moveable M; HasMove(HasMove&&); }; HasMove::HasMove(HasMove&&) = default; namespace DR1402 { struct member { member(); member(const member&); member& operator=(const member&); ~member(); }; struct A { member m_; A() = default; A(const A&) = default; A& operator=(const A&) = default; A(A&&) = default; A& operator=(A&&) = default; ~A() = default; }; // ok, A's explicitly-defaulted move operations copy m_. void f() { A a, b(a), c(static_cast(a)); a = b; b = static_cast(c); } }