summaryrefslogtreecommitdiffstats
path: root/clang/test/CXX/special/class.copy/implicit-move.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-11-04 04:26:14 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-11-04 04:26:14 +0000
commitb2504bdc0d0eb0aaf1500da08a176bd44c2ae5d0 (patch)
treef5c986b1cdc596053cb0e1738e3b1fa0382c1d9d /clang/test/CXX/special/class.copy/implicit-move.cpp
parent1c392a56115f2e21341440328316cd166e849090 (diff)
downloadbcm5719-llvm-b2504bdc0d0eb0aaf1500da08a176bd44c2ae5d0.tar.gz
bcm5719-llvm-b2504bdc0d0eb0aaf1500da08a176bd44c2ae5d0.zip
Issue a diagnostic if an implicitly-defined move assignment operator would move
the same virtual base class multiple times (and the move assignment is used, and the move assignment for the virtual base is not trivial). llvm-svn: 193977
Diffstat (limited to 'clang/test/CXX/special/class.copy/implicit-move.cpp')
-rw-r--r--clang/test/CXX/special/class.copy/implicit-move.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/clang/test/CXX/special/class.copy/implicit-move.cpp b/clang/test/CXX/special/class.copy/implicit-move.cpp
index 5c3a6027cda..23ecf2e7d95 100644
--- a/clang/test/CXX/special/class.copy/implicit-move.cpp
+++ b/clang/test/CXX/special/class.copy/implicit-move.cpp
@@ -243,6 +243,61 @@ namespace DR1402 {
(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