1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl// Tests for implicit (non-)declaration of move constructor and
485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl// assignment: p9, p11, p20, p23.
585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl// This class, used as a member, allows to distinguish move from copy because
785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl// move operations are no-throw, copy operations aren't.
885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct ThrowingCopy {
985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy() noexcept;
1085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy(ThrowingCopy &&) noexcept;
1185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy(const ThrowingCopy &) noexcept(false);
1285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy & operator =(ThrowingCopy &&) noexcept;
1385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy & operator =(const ThrowingCopy &) noexcept(false);
1485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
1585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
1685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct HasCopyConstructor {
1785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy tc;
1885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasCopyConstructor() noexcept;
1985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasCopyConstructor(const HasCopyConstructor &) noexcept(false);
2085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
2185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
2285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct HasCopyAssignment {
2385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy tc;
2485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasCopyAssignment() noexcept;
2585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false);
2685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
2785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
285bdaac5454d93d1dcdc2319818497b685be56fcfRichard Smithstruct HasMoveConstructor {
2985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy tc;
3085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasMoveConstructor() noexcept;
31e6af6604b905435456f49cd4a37da0ce6e505c38Richard Smith  HasMoveConstructor(HasMoveConstructor &&) noexcept; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}}
3285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
3385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
3485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct HasMoveAssignment { // expected-note {{implicit copy constructor}}
3585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy tc;
3685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasMoveAssignment() noexcept;
3785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasMoveAssignment & operator =(HasMoveAssignment &&) noexcept;
3885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
3985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
4085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct HasDestructor {
4185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ThrowingCopy tc;
4285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasDestructor() noexcept;
4385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ~HasDestructor() noexcept;
4485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
4585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
4685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlvoid test_basic_exclusion() {
4785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(HasCopyConstructor((HasCopyConstructor()))), "");
4885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasCopyConstructor hcc;
4985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(hcc = HasCopyConstructor()), "");
5085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
5185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(HasCopyAssignment((HasCopyAssignment()))), "");
5285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasCopyAssignment hca;
5385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(hca = HasCopyAssignment()), "");
5485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
5585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
5685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasMoveConstructor hmc;
570f46e64947bdd570a499732c4b459961627d8745Richard Smith  hmc = HasMoveConstructor(); // expected-error {{object of type 'HasMoveConstructor' cannot be assigned because its copy assignment operator is implicitly deleted}}
5885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
5985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
6085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasMoveAssignment hma;
6185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(noexcept(hma = HasMoveAssignment()), "");
6285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
6385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(HasDestructor((HasDestructor()))), "");
6485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  HasDestructor hd;
6585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(hd = HasDestructor()), "");
6685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl}
6785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
6885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct PrivateMove {
6985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateMove() noexcept;
7085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateMove(const PrivateMove &) noexcept(false);
7185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateMove & operator =(const PrivateMove &) noexcept(false);
7285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlprivate:
7385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateMove(PrivateMove &&) noexcept;
7485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateMove & operator =(PrivateMove &&) noexcept;
7585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
7685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
7785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct InheritsPrivateMove : PrivateMove {};
7885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct ContainsPrivateMove {
7985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateMove pm;
8085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
8185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
8285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct PrivateDestructor {
8385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateDestructor() noexcept;
8485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateDestructor(const PrivateDestructor &) noexcept(false);
8585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  PrivateDestructor(PrivateDestructor &&) noexcept;
8685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlprivate:
8785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ~PrivateDestructor() noexcept;
8885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
8985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
906c4c36c4ed1007143f5b8655eb68b313a7e12e76Richard Smithstruct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
916c4c36c4ed1007143f5b8655eb68b313a7e12e76Richard Smithstruct ContainsPrivateDestructor {
926c4c36c4ed1007143f5b8655eb68b313a7e12e76Richard Smith  PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}}
9385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
9485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
9585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct NonTrivialCopyOnly {
9685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  NonTrivialCopyOnly() noexcept;
9785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  NonTrivialCopyOnly(const NonTrivialCopyOnly &) noexcept(false);
9885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  NonTrivialCopyOnly & operator =(const NonTrivialCopyOnly &) noexcept(false);
9985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
10085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
10185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly {};
10285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct ContainsNonTrivialCopyOnly {
10385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  NonTrivialCopyOnly ntco;
10485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
10585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
10685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct ContainsConst {
10785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  const int i;
10885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsConst() noexcept;
10985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsConst & operator =(ContainsConst &); // expected-note {{not viable}}
11085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
11185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
11285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct ContainsRef {
11385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  int &i;
11485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsRef() noexcept;
11585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsRef & operator =(ContainsRef &); // expected-note {{not viable}}
11685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
11785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
11885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct Base {
11985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  Base & operator =(Base &);
12085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
12185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct DirectVirtualBase : virtual Base {}; // expected-note {{copy assignment operator) not viable}}
12285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct IndirectVirtualBase : DirectVirtualBase {}; // expected-note {{copy assignment operator) not viable}}
12385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
12485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlvoid test_deletion_exclusion() {
12585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  // FIXME: How to test the union thing?
12685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
12785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(InheritsPrivateMove(InheritsPrivateMove())), "");
12885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(ContainsPrivateMove(ContainsPrivateMove())), "");
12985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  InheritsPrivateMove ipm;
13085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(ipm = InheritsPrivateMove()), "");
13185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsPrivateMove cpm;
13285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(cpm = ContainsPrivateMove()), "");
13385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
134e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor  (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
135e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor  (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
13685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
13785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), "");
13885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), "");
13985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  InheritsNonTrivialCopyOnly intco;
14085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(intco = InheritsNonTrivialCopyOnly()), "");
14185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsNonTrivialCopyOnly cntco;
14285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), "");
14385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
14485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsConst cc;
14585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  cc = ContainsConst(); // expected-error {{no viable}}
14685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
14785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsRef cr;
14885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  cr = ContainsRef(); // expected-error {{no viable}}
14985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
15085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  DirectVirtualBase dvb;
15185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  dvb = DirectVirtualBase(); // expected-error {{no viable}}
15285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
15385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  IndirectVirtualBase ivb;
15485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ivb = IndirectVirtualBase(); // expected-error {{no viable}}
15585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl}
15685ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
15785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstruct ContainsRValueRef {
15885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  int&& ri;
15985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  ContainsRValueRef() noexcept;
16085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl};
16185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl
16285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlvoid test_contains_rref() {
16385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl  (ContainsRValueRef(ContainsRValueRef()));
16485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl}
1651c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith
1661c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith
1671c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smithnamespace DR1402 {
1681c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  struct NonTrivialCopyCtor {
1691c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialCopyCtor(const NonTrivialCopyCtor &);
1701c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  };
1711c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  struct NonTrivialCopyAssign {
1721c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
1731c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  };
1741c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith
1751c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor {
1761c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialCopyCtorVBase(NonTrivialCopyCtorVBase &&);
1771c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialCopyCtorVBase &operator=(NonTrivialCopyCtorVBase &&) = default;
1781c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  };
1791c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign {
1801c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialCopyAssignVBase(NonTrivialCopyAssignVBase &&);
1811c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialCopyAssignVBase &operator=(NonTrivialCopyAssignVBase &&) = default;
1821c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  };
1831c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith
1841c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  struct NonTrivialMoveAssign {
1851c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialMoveAssign(NonTrivialMoveAssign&&);
1861c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
1871c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  };
1881c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign {
1891c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialMoveAssignVBase(NonTrivialMoveAssignVBase &&);
1901c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith    NonTrivialMoveAssignVBase &operator=(NonTrivialMoveAssignVBase &&) = default;
1911c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  };
1921c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith
193743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  // DR1402: A non-movable, non-trivially-copyable class type as a subobject no
194743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  // longer inhibits the declaration of a move operation.
195743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove1 { NonTrivialCopyCtor ntcc; };
196743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove2 { NonTrivialCopyAssign ntcc; };
197743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove3 : NonTrivialCopyCtor {};
198743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove4 : NonTrivialCopyAssign {};
199743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove5 : virtual NonTrivialCopyCtor {};
200743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove6 : virtual NonTrivialCopyAssign {};
201743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove7 : NonTrivialCopyCtorVBase {};
202743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove8 : NonTrivialCopyAssignVBase {};
203743cbb91499e138a63a398c6515667905f1b3be8Richard Smith
204743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  // DR1402: A non-trivially-move-assignable virtual base class no longer
205743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  // inhibits the declaration of a move assignment (even though it might
206743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  // move-assign the base class multiple times).
2071c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  struct NoMove9 : NonTrivialMoveAssign {};
208743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove10 : virtual NonTrivialMoveAssign {};
209743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct NoMove11 : NonTrivialMoveAssignVBase {};
210743cbb91499e138a63a398c6515667905f1b3be8Richard Smith
211743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template<typename T> void test(T t) {
212743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    (void)T(static_cast<T&&>(t)); // ok
213743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    t = static_cast<T&&>(t); // ok
214743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  }
215743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove1);
216743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove2);
217743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove3);
218743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove4);
219743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove5);
220743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove6);
221743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove7);
222743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove8);
223743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove9);
224743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove10);
225743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(NoMove11);
226743cbb91499e138a63a398c6515667905f1b3be8Richard Smith
227743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct CopyOnly {
228743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    CopyOnly(const CopyOnly&);
229743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    CopyOnly &operator=(const CopyOnly&);
2301c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith  };
231743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct MoveOnly {
232743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    MoveOnly(MoveOnly&&); // expected-note {{user-declared move}}
233743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    MoveOnly &operator=(MoveOnly&&);
234743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  };
235743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(CopyOnly); // ok, copies
236743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(MoveOnly); // ok, moves
237743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  struct CopyAndMove { // expected-note {{implicitly deleted}}
238743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    CopyOnly co;
239743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    MoveOnly mo; // expected-note {{deleted copy}}
240743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  };
241743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  template void test(CopyAndMove); // ok, copies co, moves mo
242743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  void test2(CopyAndMove cm) {
243743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    (void)CopyAndMove(cm); // expected-error {{deleted}}
244743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    cm = cm; // expected-error {{deleted}}
245743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  }
24633b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
24733b1f634e074835a1b49c23d2b7674161fef1762Richard Smith  namespace VbaseMove {
24833b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct A {};
24933b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct B { B &operator=(B&&); };
25033b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct C { C &operator=(const C&); };
25133b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct D { B b; };
25233b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
25333b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template<typename T, unsigned I, bool NonTrivialMove = false>
25433b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct E : virtual T {};
25533b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
25633b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template<typename T, unsigned I>
25733b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct E<T, I, true> : virtual T { E &operator=(E&&); };
25833b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
25933b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template<typename T>
26033b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct F :
261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      E<T, 1> {}; // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
26333b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
26433b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template<typename T>
26533b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct G : E<T, 0, true>, E<T, 0> {};
26633b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
26733b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template<typename T>
26833b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct H : E<T, 0, true>, E<T, 1, true> {};
26933b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
27033b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template<typename T>
27133b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct I : E<T, 0>, T {};
27233b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
27333b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template<typename T>
27433b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    struct J :
275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      virtual T {}; // expected-note-re 2{{virtual base class '{{[BD]}}' declared here}}
27733b1f634e074835a1b49c23d2b7674161fef1762Richard Smith
27833b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template<typename T> void move(T t) { t = static_cast<T&&>(t); }
279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning-re@-1 4{{defaulted move assignment operator of {{.*}} will move assign virtual base class '{{[BD]}}' multiple times}}
28033b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(F<A>);
28133b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(F<B>); // expected-note {{in instantiation of}}
28233b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(F<C>);
28333b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(F<D>); // expected-note {{in instantiation of}}
28433b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(G<A>);
28533b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(G<B>);
28633b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(G<C>);
28733b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(G<D>);
28833b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(H<A>);
28933b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(H<B>);
29033b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(H<C>);
29133b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(H<D>);
29233b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(I<A>);
29333b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(I<B>);
29433b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(I<C>);
29533b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(I<D>);
29633b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(J<A>);
29733b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(J<B>); // expected-note {{in instantiation of}}
29833b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(J<C>);
29933b1f634e074835a1b49c23d2b7674161fef1762Richard Smith    template void move(J<D>); // expected-note {{in instantiation of}}
30033b1f634e074835a1b49c23d2b7674161fef1762Richard Smith  }
3011c931be1873f8c20cdcb5060c84570cd3359aa02Richard Smith}
3025d59b79c2fd8783900e52cf2dd6add5d3627b2fcRichard Smith
3035d59b79c2fd8783900e52cf2dd6add5d3627b2fcRichard Smithnamespace PR12625 {
3045d59b79c2fd8783900e52cf2dd6add5d3627b2fcRichard Smith  struct X; // expected-note {{forward decl}}
3055d59b79c2fd8783900e52cf2dd6add5d3627b2fcRichard Smith  struct Y {
3065d59b79c2fd8783900e52cf2dd6add5d3627b2fcRichard Smith    X x; // expected-error {{incomplete}}
3075d59b79c2fd8783900e52cf2dd6add5d3627b2fcRichard Smith  } y = Y();
3085d59b79c2fd8783900e52cf2dd6add5d3627b2fcRichard Smith}
309