diff options
Diffstat (limited to 'test/CXX/special/class.copy/implicit-move.cpp')
| -rw-r--r-- | test/CXX/special/class.copy/implicit-move.cpp | 147 | 
1 files changed, 106 insertions, 41 deletions
diff --git a/test/CXX/special/class.copy/implicit-move.cpp b/test/CXX/special/class.copy/implicit-move.cpp index 33374129f7185..23ecf2e7d95ab 100644 --- a/test/CXX/special/class.copy/implicit-move.cpp +++ b/test/CXX/special/class.copy/implicit-move.cpp @@ -190,49 +190,114 @@ namespace DR1402 {      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 &'}} -  struct NoMove7 : NonTrivialCopyCtorVBase {}; // expected-note 2{{'const DR1402::NoMove7 &'}} -  struct NoMove8 : NonTrivialCopyAssignVBase {}; // expected-note 2{{'const DR1402::NoMove8 &'}} - -  // A non-trivially-move-assignable virtual base class inhibits the declaration -  // of a move assignment (which might move-assign the base class multiple -  // times). +  // DR1402: A non-movable, non-trivially-copyable class type as a subobject no +  // longer inhibits the declaration of a move operation. +  struct NoMove1 { NonTrivialCopyCtor ntcc; }; +  struct NoMove2 { NonTrivialCopyAssign ntcc; }; +  struct NoMove3 : NonTrivialCopyCtor {}; +  struct NoMove4 : NonTrivialCopyAssign {}; +  struct NoMove5 : virtual NonTrivialCopyCtor {}; +  struct NoMove6 : virtual NonTrivialCopyAssign {}; +  struct NoMove7 : NonTrivialCopyCtorVBase {}; +  struct NoMove8 : NonTrivialCopyAssignVBase {}; + +  // DR1402: A non-trivially-move-assignable virtual base class no longer +  // inhibits the declaration of a move assignment (even though it might +  // move-assign the base class multiple times).    struct NoMove9 : NonTrivialMoveAssign {}; -  struct NoMove10 : virtual NonTrivialMoveAssign {}; // expected-note {{'const DR1402::NoMove10 &'}} -  struct NoMove11 : NonTrivialMoveAssignVBase {}; // expected-note {{'const DR1402::NoMove11 &'}} - -  struct Test { -    friend NoMove1::NoMove1(NoMove1 &&); // expected-error {{no matching function}} -    friend NoMove2::NoMove2(NoMove2 &&); // expected-error {{no matching function}} -    friend NoMove3::NoMove3(NoMove3 &&); // expected-error {{no matching function}} -    friend NoMove4::NoMove4(NoMove4 &&); // expected-error {{no matching function}} -    friend NoMove5::NoMove5(NoMove5 &&); // expected-error {{no matching function}} -    friend NoMove6::NoMove6(NoMove6 &&); // expected-error {{no matching function}} -    friend NoMove7::NoMove7(NoMove7 &&); // expected-error {{no matching function}} -    friend NoMove8::NoMove8(NoMove8 &&); // expected-error {{no matching function}} -    friend NoMove9::NoMove9(NoMove9 &&); -    friend NoMove10::NoMove10(NoMove10 &&); -    friend NoMove11::NoMove11(NoMove11 &&); - -    friend NoMove1 &NoMove1::operator=(NoMove1 &&); // expected-error {{no matching function}} -    friend NoMove2 &NoMove2::operator=(NoMove2 &&); // expected-error {{no matching function}} -    friend NoMove3 &NoMove3::operator=(NoMove3 &&); // expected-error {{no matching function}} -    friend NoMove4 &NoMove4::operator=(NoMove4 &&); // expected-error {{no matching function}} -    friend NoMove5 &NoMove5::operator=(NoMove5 &&); // expected-error {{no matching function}} -    friend NoMove6 &NoMove6::operator=(NoMove6 &&); // expected-error {{no matching function}} -    friend NoMove7 &NoMove7::operator=(NoMove7 &&); // expected-error {{no matching function}} -    friend NoMove8 &NoMove8::operator=(NoMove8 &&); // expected-error {{no matching function}} -    friend NoMove9 &NoMove9::operator=(NoMove9 &&); -    friend NoMove10 &NoMove10::operator=(NoMove10 &&); // expected-error {{no matching function}} -    friend NoMove11 &NoMove11::operator=(NoMove11 &&); // expected-error {{no matching function}} +  struct NoMove10 : virtual NonTrivialMoveAssign {}; +  struct NoMove11 : NonTrivialMoveAssignVBase {}; + +  template<typename T> void test(T t) { +    (void)T(static_cast<T&&>(t)); // ok +    t = static_cast<T&&>(t); // ok +  } +  template void test(NoMove1); +  template void test(NoMove2); +  template void test(NoMove3); +  template void test(NoMove4); +  template void test(NoMove5); +  template void test(NoMove6); +  template void test(NoMove7); +  template void test(NoMove8); +  template void test(NoMove9); +  template void test(NoMove10); +  template void test(NoMove11); + +  struct CopyOnly { +    CopyOnly(const CopyOnly&); +    CopyOnly &operator=(const CopyOnly&);    }; +  struct MoveOnly { +    MoveOnly(MoveOnly&&); // expected-note {{user-declared move}} +    MoveOnly &operator=(MoveOnly&&); +  }; +  template void test(CopyOnly); // ok, copies +  template void test(MoveOnly); // ok, moves +  struct CopyAndMove { // expected-note {{implicitly deleted}} +    CopyOnly co; +    MoveOnly mo; // expected-note {{deleted copy}} +  }; +  template void test(CopyAndMove); // ok, copies co, moves mo +  void test2(CopyAndMove cm) { +    (void)CopyAndMove(cm); // expected-error {{deleted}} +    cm = cm; // expected-error {{deleted}} +  } + +  namespace VbaseMove { +    struct A {}; +    struct B { B &operator=(B&&); }; +    struct C { C &operator=(const C&); }; +    struct D { B b; }; + +    template<typename T, unsigned I, bool NonTrivialMove = false> +    struct E : virtual T {}; + +    template<typename T, unsigned I> +    struct E<T, I, true> : virtual T { E &operator=(E&&); }; + +    template<typename T> +    struct F : +      E<T, 0>, // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}} +      E<T, 1> {}; // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}} + +    template<typename T> +    struct G : E<T, 0, true>, E<T, 0> {}; + +    template<typename T> +    struct H : E<T, 0, true>, E<T, 1, true> {}; + +    template<typename T> +    struct I : E<T, 0>, T {}; + +    template<typename T> +    struct J : +      E<T, 0>, // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}} +      virtual T {}; // expected-note-re 2{{virtual base class '[BD]' declared here}} + +    template<typename T> void move(T t) { t = static_cast<T&&>(t); } +    // expected-warning-re@-1 4{{defaulted move assignment operator of .* will move assign virtual base class '[BD]' multiple times}} +    template void move(F<A>); +    template void move(F<B>); // expected-note {{in instantiation of}} +    template void move(F<C>); +    template void move(F<D>); // expected-note {{in instantiation of}} +    template void move(G<A>); +    template void move(G<B>); +    template void move(G<C>); +    template void move(G<D>); +    template void move(H<A>); +    template void move(H<B>); +    template void move(H<C>); +    template void move(H<D>); +    template void move(I<A>); +    template void move(I<B>); +    template void move(I<C>); +    template void move(I<D>); +    template void move(J<A>); +    template void move(J<B>); // expected-note {{in instantiation of}} +    template void move(J<C>); +    template void move(J<D>); // expected-note {{in instantiation of}} +  }  }  namespace PR12625 {  | 
