diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-11-04 04:26:14 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-11-04 04:26:14 +0000 |
commit | b2504bdc0d0eb0aaf1500da08a176bd44c2ae5d0 (patch) | |
tree | f5c986b1cdc596053cb0e1738e3b1fa0382c1d9d /clang/test/CXX/special/class.copy/implicit-move.cpp | |
parent | 1c392a56115f2e21341440328316cd166e849090 (diff) | |
download | bcm5719-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.cpp | 55 |
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 { |