summaryrefslogtreecommitdiffstats
path: root/test/CXX/special/class.copy/implicit-move.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX/special/class.copy/implicit-move.cpp')
-rw-r--r--test/CXX/special/class.copy/implicit-move.cpp147
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 3337412..23ecf2e 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 {
OpenPOWER on IntegriCloud