2011-10-14 06:29:44 +08:00
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2011-10-11 14:43:29 +08:00
2013-11-25 15:07:05 +08:00
struct Trivial { } ;
2011-10-11 14:43:29 +08:00
struct NonTrivial {
2014-01-23 04:09:10 +08:00
NonTrivial ( NonTrivial & & ) ; // expected-note{{copy constructor is implicitly deleted}}
2011-10-11 14:43:29 +08:00
} ;
2016-08-16 08:13:47 +08:00
struct DeletedCopy {
DeletedCopy ( const DeletedCopy & ) = delete ;
} ;
2011-10-11 14:43:29 +08:00
2012-03-04 07:51:05 +08:00
// A defaulted move constructor for a class X is defined as deleted if X has:
// -- a variant member with a non-trivial corresponding constructor
2011-10-11 14:43:29 +08:00
union DeletedNTVariant {
2014-01-23 04:09:10 +08:00
NonTrivial NT ; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
2011-10-11 14:43:29 +08:00
DeletedNTVariant ( DeletedNTVariant & & ) ;
} ;
DeletedNTVariant : : DeletedNTVariant ( DeletedNTVariant & & ) = default ; // expected-error{{would delete}}
struct DeletedNTVariant2 {
union {
2014-01-23 04:09:10 +08:00
NonTrivial NT ; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
2011-10-11 14:43:29 +08:00
} ;
DeletedNTVariant2 ( DeletedNTVariant2 & & ) ;
} ;
DeletedNTVariant2 : : DeletedNTVariant2 ( DeletedNTVariant2 & & ) = default ; // expected-error{{would delete}}
2016-08-16 08:13:47 +08:00
// Note, move constructor is not a candidate because it is deleted.
template < typename T > struct DeletedNTVariant3 { // expected-note 2{{default}} expected-note 2{{copy}}
union {
T NT ;
} ;
} ;
extern DeletedNTVariant3 < NonTrivial > dntv3a ( 0 ) ; // expected-error {{no matching}}
extern DeletedNTVariant3 < DeletedCopy > dntv3a ( 0 ) ; // expected-error {{no matching}}
2012-03-04 07:51:05 +08:00
// -- 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
2011-10-11 14:43:29 +08:00
struct NoAccess {
NoAccess ( ) = default ;
private :
NoAccess ( NoAccess & & ) ;
friend struct HasAccess ;
} ;
struct HasNoAccess {
2014-01-23 04:09:10 +08:00
NoAccess NA ; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}
2011-10-11 14:43:29 +08:00
HasNoAccess ( HasNoAccess & & ) ;
} ;
HasNoAccess : : HasNoAccess ( HasNoAccess & & ) = default ; // expected-error{{would delete}}
struct HasAccess {
NoAccess NA ;
HasAccess ( HasAccess & & ) ;
} ;
HasAccess : : HasAccess ( HasAccess & & ) = default ;
2012-03-04 07:51:05 +08:00
struct Ambiguity {
Ambiguity ( const Ambiguity & & ) ;
Ambiguity ( volatile Ambiguity & & ) ;
} ;
struct IsAmbiguous {
2014-01-23 04:09:10 +08:00
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}}
2012-03-04 07:51:05 +08:00
} ;
IsAmbiguous : : IsAmbiguous ( IsAmbiguous & & ) = default ; // expected-error{{would delete}}
struct Deleted {
2014-01-23 04:09:10 +08:00
// 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}}
2012-03-04 07:51:05 +08:00
Deleted ( Deleted & & ) ;
} ;
Deleted : : Deleted ( Deleted & & ) = default ; // expected-error{{would delete}}
2013-11-25 15:07:05 +08:00
// 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 {
2014-01-23 04:09:10 +08:00
// 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}}
2013-11-25 15:07:05 +08:00
ConstMoveOnlyMember ( ConstMoveOnlyMember & & ) ;
} ;
ConstMoveOnlyMember : : ConstMoveOnlyMember ( ConstMoveOnlyMember & & ) = default ; // expected-error{{would delete}}
struct VolatileMember {
2014-01-23 04:09:10 +08:00
volatile Trivial vt ; // expected-note{{deleted because field 'vt' has no move constructor}}
2013-11-25 15:07:05 +08:00
VolatileMember ( VolatileMember & & ) ;
} ;
VolatileMember : : VolatileMember ( VolatileMember & & ) = default ; // expected-error{{would delete}}
2012-03-04 07:51:05 +08:00
// -- 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
2014-01-23 04:09:10 +08:00
struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}
AmbiguousMoveBase ( AmbiguousMoveBase & & ) ; // expected-note{{copy constructor is implicitly deleted}}
2012-03-04 07:51:05 +08:00
} ;
AmbiguousMoveBase : : AmbiguousMoveBase ( AmbiguousMoveBase & & ) = default ; // expected-error{{would delete}}
2014-01-23 04:09:10 +08:00
struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}}
2012-03-04 07:51:05 +08:00
DeletedMoveBase ( DeletedMoveBase & & ) ;
} ;
DeletedMoveBase : : DeletedMoveBase ( DeletedMoveBase & & ) = default ; // expected-error{{would delete}}
2014-01-23 04:09:10 +08:00
struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}}
2012-03-04 07:51:05 +08:00
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
2011-10-11 14:43:29 +08:00
struct NoAccessDtor {
2012-03-31 04:53:28 +08:00
NoAccessDtor ( NoAccessDtor & & ) ; // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}
2011-10-11 14:43:29 +08:00
private :
~ NoAccessDtor ( ) ;
friend struct HasAccessDtor ;
} ;
struct HasNoAccessDtor {
2014-01-23 04:09:10 +08:00
NoAccessDtor NAD ; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}
2011-10-11 14:43:29 +08:00
HasNoAccessDtor ( HasNoAccessDtor & & ) ;
} ;
HasNoAccessDtor : : HasNoAccessDtor ( HasNoAccessDtor & & ) = default ; // expected-error{{would delete}}
struct HasAccessDtor {
NoAccessDtor NAD ;
HasAccessDtor ( HasAccessDtor & & ) ;
} ;
HasAccessDtor : : HasAccessDtor ( HasAccessDtor & & ) = default ;
2012-03-31 04:53:28 +08:00
struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}
2012-03-04 07:51:05 +08:00
} ;
extern HasNoAccessDtorBase HNADBa ;
HasNoAccessDtorBase HNADBb ( HNADBa ) ; // expected-error{{implicitly-deleted copy constructor}}
// The restriction on rvalue reference members applies to only the copy
// constructor.
2011-10-11 14:43:29 +08:00
struct RValue {
2018-07-18 06:24:09 +08:00
int & & ri = 1 ;
2011-10-11 14:43:29 +08:00
RValue ( RValue & & ) ;
} ;
RValue : : RValue ( RValue & & ) = default ;
2012-03-04 07:51:05 +08:00
// -- 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
2011-10-11 14:43:29 +08:00
struct CopyOnly {
CopyOnly ( const CopyOnly & ) ;
} ;
struct NonMove {
CopyOnly CO ;
NonMove ( NonMove & & ) ;
} ;
2012-04-03 02:40:40 +08:00
NonMove : : NonMove ( NonMove & & ) = default ; // ok under DR1402
2011-10-11 14:43:29 +08:00
struct Moveable {
Moveable ( ) ;
Moveable ( Moveable & & ) ;
} ;
struct HasMove {
Moveable M ;
HasMove ( HasMove & & ) ;
} ;
HasMove : : HasMove ( HasMove & & ) = default ;
2012-04-03 02:40:40 +08:00
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 ) ) ;
a = b ;
b = static_cast < A & & > ( c ) ;
}
}