2011-10-14 06:29:44 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2011-08-31 03:58:05 +08:00
// Tests for implicit (non-)declaration of move constructor and
// assignment: p9, p11, p20, p23.
// This class, used as a member, allows to distinguish move from copy because
// move operations are no-throw, copy operations aren't.
struct ThrowingCopy {
ThrowingCopy ( ) noexcept ;
ThrowingCopy ( ThrowingCopy & & ) noexcept ;
ThrowingCopy ( const ThrowingCopy & ) noexcept ( false ) ;
ThrowingCopy & operator = ( ThrowingCopy & & ) noexcept ;
ThrowingCopy & operator = ( const ThrowingCopy & ) noexcept ( false ) ;
} ;
struct HasCopyConstructor {
ThrowingCopy tc ;
HasCopyConstructor ( ) noexcept ;
HasCopyConstructor ( const HasCopyConstructor & ) noexcept ( false ) ;
} ;
struct HasCopyAssignment {
ThrowingCopy tc ;
HasCopyAssignment ( ) noexcept ;
HasCopyAssignment & operator = ( const HasCopyAssignment & ) noexcept ( false ) ;
} ;
2012-04-03 04:59:25 +08:00
struct HasMoveConstructor {
2011-08-31 03:58:05 +08:00
ThrowingCopy tc ;
HasMoveConstructor ( ) noexcept ;
2012-04-03 05:07:48 +08:00
HasMoveConstructor ( HasMoveConstructor & & ) noexcept ; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}}
2011-08-31 03:58:05 +08:00
} ;
struct HasMoveAssignment { // expected-note {{implicit copy constructor}}
ThrowingCopy tc ;
HasMoveAssignment ( ) noexcept ;
HasMoveAssignment & operator = ( HasMoveAssignment & & ) noexcept ;
} ;
struct HasDestructor {
ThrowingCopy tc ;
HasDestructor ( ) noexcept ;
~ HasDestructor ( ) noexcept ;
} ;
void test_basic_exclusion ( ) {
static_assert ( ! noexcept ( HasCopyConstructor ( ( HasCopyConstructor ( ) ) ) ) , " " ) ;
HasCopyConstructor hcc ;
static_assert ( ! noexcept ( hcc = HasCopyConstructor ( ) ) , " " ) ;
static_assert ( ! noexcept ( HasCopyAssignment ( ( HasCopyAssignment ( ) ) ) ) , " " ) ;
HasCopyAssignment hca ;
static_assert ( ! noexcept ( hca = HasCopyAssignment ( ) ) , " " ) ;
static_assert ( noexcept ( HasMoveConstructor ( ( HasMoveConstructor ( ) ) ) ) , " " ) ;
HasMoveConstructor hmc ;
2012-12-28 20:23:24 +08:00
hmc = HasMoveConstructor ( ) ; // expected-error {{object of type 'HasMoveConstructor' cannot be assigned because its copy assignment operator is implicitly deleted}}
2011-08-31 03:58:05 +08:00
( HasMoveAssignment ( HasMoveAssignment ( ) ) ) ; // expected-error {{uses deleted function}}
HasMoveAssignment hma ;
static_assert ( noexcept ( hma = HasMoveAssignment ( ) ) , " " ) ;
static_assert ( ! noexcept ( HasDestructor ( ( HasDestructor ( ) ) ) ) , " " ) ;
HasDestructor hd ;
static_assert ( ! noexcept ( hd = HasDestructor ( ) ) , " " ) ;
}
struct PrivateMove {
PrivateMove ( ) noexcept ;
PrivateMove ( const PrivateMove & ) noexcept ( false ) ;
PrivateMove & operator = ( const PrivateMove & ) noexcept ( false ) ;
private :
PrivateMove ( PrivateMove & & ) noexcept ;
PrivateMove & operator = ( PrivateMove & & ) noexcept ;
} ;
struct InheritsPrivateMove : PrivateMove { } ;
struct ContainsPrivateMove {
PrivateMove pm ;
} ;
struct PrivateDestructor {
PrivateDestructor ( ) noexcept ;
PrivateDestructor ( const PrivateDestructor & ) noexcept ( false ) ;
PrivateDestructor ( PrivateDestructor & & ) noexcept ;
private :
~ PrivateDestructor ( ) noexcept ;
} ;
2012-03-31 04:53:28 +08:00
struct InheritsPrivateDestructor : PrivateDestructor { } ; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
struct ContainsPrivateDestructor {
PrivateDestructor pd ; // expected-note{{field 'pd' has an inaccessible destructor}}
2011-08-31 03:58:05 +08:00
} ;
struct NonTrivialCopyOnly {
NonTrivialCopyOnly ( ) noexcept ;
NonTrivialCopyOnly ( const NonTrivialCopyOnly & ) noexcept ( false ) ;
NonTrivialCopyOnly & operator = ( const NonTrivialCopyOnly & ) noexcept ( false ) ;
} ;
struct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly { } ;
struct ContainsNonTrivialCopyOnly {
NonTrivialCopyOnly ntco ;
} ;
struct ContainsConst {
const int i ;
ContainsConst ( ) noexcept ;
ContainsConst & operator = ( ContainsConst & ) ; // expected-note {{not viable}}
} ;
struct ContainsRef {
int & i ;
ContainsRef ( ) noexcept ;
ContainsRef & operator = ( ContainsRef & ) ; // expected-note {{not viable}}
} ;
struct Base {
Base & operator = ( Base & ) ;
} ;
struct DirectVirtualBase : virtual Base { } ; // expected-note {{copy assignment operator) not viable}}
struct IndirectVirtualBase : DirectVirtualBase { } ; // expected-note {{copy assignment operator) not viable}}
void test_deletion_exclusion ( ) {
// FIXME: How to test the union thing?
static_assert ( ! noexcept ( InheritsPrivateMove ( InheritsPrivateMove ( ) ) ) , " " ) ;
static_assert ( ! noexcept ( ContainsPrivateMove ( ContainsPrivateMove ( ) ) ) , " " ) ;
InheritsPrivateMove ipm ;
static_assert ( ! noexcept ( ipm = InheritsPrivateMove ( ) ) , " " ) ;
ContainsPrivateMove cpm ;
static_assert ( ! noexcept ( cpm = ContainsPrivateMove ( ) ) , " " ) ;
2012-02-16 03:33:52 +08:00
( InheritsPrivateDestructor ( InheritsPrivateDestructor ( ) ) ) ; // expected-error {{call to implicitly-deleted default constructor}}
( ContainsPrivateDestructor ( ContainsPrivateDestructor ( ) ) ) ; // expected-error {{call to implicitly-deleted default constructor}}
2011-08-31 03:58:05 +08:00
static_assert ( ! noexcept ( InheritsNonTrivialCopyOnly ( InheritsNonTrivialCopyOnly ( ) ) ) , " " ) ;
static_assert ( ! noexcept ( ContainsNonTrivialCopyOnly ( ContainsNonTrivialCopyOnly ( ) ) ) , " " ) ;
InheritsNonTrivialCopyOnly intco ;
static_assert ( ! noexcept ( intco = InheritsNonTrivialCopyOnly ( ) ) , " " ) ;
ContainsNonTrivialCopyOnly cntco ;
static_assert ( ! noexcept ( cntco = ContainsNonTrivialCopyOnly ( ) ) , " " ) ;
ContainsConst cc ;
cc = ContainsConst ( ) ; // expected-error {{no viable}}
ContainsRef cr ;
cr = ContainsRef ( ) ; // expected-error {{no viable}}
DirectVirtualBase dvb ;
dvb = DirectVirtualBase ( ) ; // expected-error {{no viable}}
IndirectVirtualBase ivb ;
ivb = IndirectVirtualBase ( ) ; // expected-error {{no viable}}
}
struct ContainsRValueRef {
int & & ri ;
ContainsRValueRef ( ) noexcept ;
} ;
void test_contains_rref ( ) {
( ContainsRValueRef ( ContainsRValueRef ( ) ) ) ;
}
2012-04-03 02:40:40 +08:00
namespace DR1402 {
struct NonTrivialCopyCtor {
NonTrivialCopyCtor ( const NonTrivialCopyCtor & ) ;
} ;
struct NonTrivialCopyAssign {
NonTrivialCopyAssign & operator = ( const NonTrivialCopyAssign & ) ;
} ;
struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor {
NonTrivialCopyCtorVBase ( NonTrivialCopyCtorVBase & & ) ;
NonTrivialCopyCtorVBase & operator = ( NonTrivialCopyCtorVBase & & ) = default ;
} ;
struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign {
NonTrivialCopyAssignVBase ( NonTrivialCopyAssignVBase & & ) ;
NonTrivialCopyAssignVBase & operator = ( NonTrivialCopyAssignVBase & & ) = default ;
} ;
struct NonTrivialMoveAssign {
NonTrivialMoveAssign ( NonTrivialMoveAssign & & ) ;
NonTrivialMoveAssign & operator = ( NonTrivialMoveAssign & & ) ;
} ;
struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign {
NonTrivialMoveAssignVBase ( NonTrivialMoveAssignVBase & & ) ;
NonTrivialMoveAssignVBase & operator = ( NonTrivialMoveAssignVBase & & ) = default ;
} ;
// A non-movable, non-trivially-copyable class type as a subobject inhibits
// the declaration of a move operation.
struct NoMove1 { NonTrivialCopyCtor ntcc ; } ; // expected-note 2{{'const DR1402::NoMove1 &'}}
struct NoMove2 { NonTrivialCopyAssign ntcc ; } ; // expected-note 2{{'const DR1402::NoMove2 &'}}
struct NoMove3 : NonTrivialCopyCtor { } ; // expected-note 2{{'const DR1402::NoMove3 &'}}
struct NoMove4 : NonTrivialCopyAssign { } ; // expected-note 2{{'const DR1402::NoMove4 &'}}
struct NoMove5 : virtual NonTrivialCopyCtor { } ; // expected-note 2{{'const DR1402::NoMove5 &'}}
struct NoMove6 : virtual NonTrivialCopyAssign { } ; // expected-note 2{{'const DR1402::NoMove6 &'}}
2012-04-21 02:46:14 +08:00
struct NoMove7 : NonTrivialCopyCtorVBase { } ; // expected-note 2{{'const DR1402::NoMove7 &'}}
struct NoMove8 : NonTrivialCopyAssignVBase { } ; // expected-note 2{{'const DR1402::NoMove8 &'}}
2012-04-03 02:40:40 +08:00
// A non-trivially-move-assignable virtual base class inhibits the declaration
// of a move assignment (which might move-assign the base class multiple
// times).
struct NoMove9 : NonTrivialMoveAssign { } ;
2012-04-21 02:46:14 +08:00
struct NoMove10 : virtual NonTrivialMoveAssign { } ; // expected-note {{'const DR1402::NoMove10 &'}}
struct NoMove11 : NonTrivialMoveAssignVBase { } ; // expected-note {{'const DR1402::NoMove11 &'}}
2012-04-03 02:40:40 +08:00
struct Test {
2013-08-09 12:35:01 +08:00
friend NoMove1 : : NoMove1 ( NoMove1 & & ) ; // expected-error {{does not match}}
friend NoMove2 : : NoMove2 ( NoMove2 & & ) ; // expected-error {{does not match}}
friend NoMove3 : : NoMove3 ( NoMove3 & & ) ; // expected-error {{does not match}}
friend NoMove4 : : NoMove4 ( NoMove4 & & ) ; // expected-error {{does not match}}
friend NoMove5 : : NoMove5 ( NoMove5 & & ) ; // expected-error {{does not match}}
friend NoMove6 : : NoMove6 ( NoMove6 & & ) ; // expected-error {{does not match}}
friend NoMove7 : : NoMove7 ( NoMove7 & & ) ; // expected-error {{does not match}}
friend NoMove8 : : NoMove8 ( NoMove8 & & ) ; // expected-error {{does not match}}
2012-04-03 02:40:40 +08:00
friend NoMove9 : : NoMove9 ( NoMove9 & & ) ;
friend NoMove10 : : NoMove10 ( NoMove10 & & ) ;
friend NoMove11 : : NoMove11 ( NoMove11 & & ) ;
2013-08-09 12:35:01 +08:00
friend NoMove1 & NoMove1 : : operator = ( NoMove1 & & ) ; // expected-error {{does not match}}
friend NoMove2 & NoMove2 : : operator = ( NoMove2 & & ) ; // expected-error {{does not match}}
friend NoMove3 & NoMove3 : : operator = ( NoMove3 & & ) ; // expected-error {{does not match}}
friend NoMove4 & NoMove4 : : operator = ( NoMove4 & & ) ; // expected-error {{does not match}}
friend NoMove5 & NoMove5 : : operator = ( NoMove5 & & ) ; // expected-error {{does not match}}
friend NoMove6 & NoMove6 : : operator = ( NoMove6 & & ) ; // expected-error {{does not match}}
friend NoMove7 & NoMove7 : : operator = ( NoMove7 & & ) ; // expected-error {{does not match}}
friend NoMove8 & NoMove8 : : operator = ( NoMove8 & & ) ; // expected-error {{does not match}}
2012-04-03 02:40:40 +08:00
friend NoMove9 & NoMove9 : : operator = ( NoMove9 & & ) ;
2013-08-09 12:35:01 +08:00
friend NoMove10 & NoMove10 : : operator = ( NoMove10 & & ) ; // expected-error {{does not match}}
friend NoMove11 & NoMove11 : : operator = ( NoMove11 & & ) ; // expected-error {{does not match}}
2012-04-03 02:40:40 +08:00
} ;
}
2012-04-26 02:28:49 +08:00
namespace PR12625 {
struct X ; // expected-note {{forward decl}}
struct Y {
X x ; // expected-error {{incomplete}}
} y = Y ( ) ;
}