diff options
author | dim <dim@FreeBSD.org> | 2013-12-22 00:07:40 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-12-22 00:07:40 +0000 |
commit | 952eddef9aff85b1e92626e89baaf7a360e2ac85 (patch) | |
tree | df8df0b0067b381eab470a3b8f28d14a552a6340 /test/CXX/special/class.copy | |
parent | ea266cad53e3d49771fa38103913d3ec7a166694 (diff) | |
download | FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.zip FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.tar.gz |
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841
Diffstat (limited to 'test/CXX/special/class.copy')
-rw-r--r-- | test/CXX/special/class.copy/implicit-move-def.cpp | 2 | ||||
-rw-r--r-- | test/CXX/special/class.copy/implicit-move.cpp | 147 | ||||
-rw-r--r-- | test/CXX/special/class.copy/p11.0x.copy.cpp | 8 | ||||
-rw-r--r-- | test/CXX/special/class.copy/p11.0x.move.cpp | 21 | ||||
-rw-r--r-- | test/CXX/special/class.copy/p12-0x.cpp | 4 | ||||
-rw-r--r-- | test/CXX/special/class.copy/p23-cxx11.cpp | 38 |
6 files changed, 170 insertions, 50 deletions
diff --git a/test/CXX/special/class.copy/implicit-move-def.cpp b/test/CXX/special/class.copy/implicit-move-def.cpp index 5c54aea..5696d1f 100644 --- a/test/CXX/special/class.copy/implicit-move-def.cpp +++ b/test/CXX/special/class.copy/implicit-move-def.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-ASSIGN %s +// FIXME: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK %s // RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-ASSIGN %s // RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-CTOR %s 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 { diff --git a/test/CXX/special/class.copy/p11.0x.copy.cpp b/test/CXX/special/class.copy/p11.0x.copy.cpp index fab3b9d..a334c50 100644 --- a/test/CXX/special/class.copy/p11.0x.copy.cpp +++ b/test/CXX/special/class.copy/p11.0x.copy.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +struct Trivial {}; struct NonTrivial { NonTrivial(const NonTrivial&); }; @@ -69,6 +70,12 @@ struct Deleted { Deleted Da; Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}} +// It's implied (but not stated) that this also applies in the case where +// overload resolution would fail. +struct VolatileMember { + volatile Trivial vm; // expected-note {{has no copy}} +} vm1, vm2(vm1); // expected-error {{deleted}} + // -- a direct or virtual base class B that cannot be copied because overload // resolution results in an ambiguity or a function that is deleted or // inaccessible @@ -116,6 +123,7 @@ HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy c // -- a non-static data member of rvalue reference type struct RValue { int && ri = 1; // expected-note{{copy constructor of 'RValue' is implicitly deleted because field 'ri' is of rvalue reference type 'int &&'}} + // expected-warning@-1{{binding reference member 'ri' to a temporary}} expected-note@-1 {{here}} }; RValue RVa; RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}} diff --git a/test/CXX/special/class.copy/p11.0x.move.cpp b/test/CXX/special/class.copy/p11.0x.move.cpp index ff9478b..1dce27a 100644 --- a/test/CXX/special/class.copy/p11.0x.move.cpp +++ b/test/CXX/special/class.copy/p11.0x.move.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +struct Trivial {}; struct NonTrivial { NonTrivial(NonTrivial&&); }; @@ -61,6 +62,24 @@ struct Deleted { }; Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}} +// It's implied (but not stated) that this should also happen if overload +// resolution fails. +struct ConstMember { + const Trivial ct; + ConstMember(ConstMember&&); +}; +ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor +struct ConstMoveOnlyMember { + const NonTrivial cnt; + ConstMoveOnlyMember(ConstMoveOnlyMember&&); +}; +ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}} +struct VolatileMember { + volatile Trivial vt; + VolatileMember(VolatileMember&&); +}; +VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}} + // -- a direct or virtual base class B that cannot be moved because overload // resolution results in an ambiguity or a function that is deleted or // inaccessible @@ -108,7 +127,7 @@ HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy c // The restriction on rvalue reference members applies to only the copy // constructor. struct RValue { - int &&ri = 1; + int &&ri = 1; // expected-warning {{binding reference member 'ri' to a temporary}} expected-note {{here}} RValue(RValue&&); }; RValue::RValue(RValue&&) = default; diff --git a/test/CXX/special/class.copy/p12-0x.cpp b/test/CXX/special/class.copy/p12-0x.cpp index 17b3191..1b23b5a 100644 --- a/test/CXX/special/class.copy/p12-0x.cpp +++ b/test/CXX/special/class.copy/p12-0x.cpp @@ -157,8 +157,8 @@ namespace TrivialityDependsOnImplicitDeletion { struct NoAccess { PrivateMove pm; - // NoAccess's move would be deleted, so is suppressed, - // so moves of it use PrivateMove's copy ctor, which is trivial. + // NoAccess's move is deleted, so moves of it use PrivateMove's copy ctor, + // which is trivial. }; static_assert(__is_trivially_constructible(NoAccess, const NoAccess &), ""); static_assert(__is_trivially_constructible(NoAccess, NoAccess &&), ""); diff --git a/test/CXX/special/class.copy/p23-cxx11.cpp b/test/CXX/special/class.copy/p23-cxx11.cpp index 90945c5..de071f0 100644 --- a/test/CXX/special/class.copy/p23-cxx11.cpp +++ b/test/CXX/special/class.copy/p23-cxx11.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -verify %s -std=c++11 +struct Trivial {}; + template<typename T> struct CopyAssign { static T t; void test() { @@ -9,7 +11,15 @@ template<typename T> struct CopyAssign { template<typename T> struct MoveAssign { static T t; void test() { - t = static_cast<T&&>(t); // expected-error +{{deleted}} + // Overload resolution will ignore a defaulted, deleted move assignment, + // so check for it in a different way. + T &(T::*f)(T&&) = &T::operator=; // expected-error +{{deleted}} + } +}; +template<typename T> struct MoveOrCopyAssign { + static T t; + void test() { + t = static_cast<T&&>(t); // expected-error +{{copy assignment operator is implicitly deleted}} } }; @@ -39,6 +49,9 @@ class InaccessibleCopyAssign { class InaccessibleMoveAssign { InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&); }; +class NonConstCopyAssign { + NonConstCopyAssign &operator=(NonConstCopyAssign &); +}; // A defaulted copy/move assignment operator for class X is defined as deleted // if X has: @@ -89,29 +102,44 @@ struct D1 { AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}} }; struct D2 { - D2 &operator=(D2 &&) = default; // expected-note {{here}} + D2 &operator=(D2 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}} }; struct D3 { DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}} }; struct D4 { - D4 &operator=(D4 &&) = default; // expected-note {{here}} + D4 &operator=(D4 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}} }; struct D5 { InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}} }; struct D6 { - D6 &operator=(D6 &&) = default; // expected-note {{here}} + D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}} }; +struct D7 { + const Trivial a; // expected-note 3{{field 'a' has no }} +}; +struct D8 { + volatile Trivial a; // expected-note 3{{field 'a' has no }} +}; template struct CopyAssign<D1>; // expected-note {{here}} template struct MoveAssign<D2>; // expected-note {{here}} +template struct MoveOrCopyAssign<D2>; // expected-note {{here}} template struct CopyAssign<D3>; // expected-note {{here}} template struct MoveAssign<D4>; // expected-note {{here}} +template struct MoveOrCopyAssign<D4>; // expected-note {{here}} template struct CopyAssign<D5>; // expected-note {{here}} template struct MoveAssign<D6>; // expected-note {{here}} +template struct MoveOrCopyAssign<D6>; // expected-note {{here}} +template struct CopyAssign<D7>; // expected-note {{here}} +template struct MoveAssign<D7>; // expected-note {{here}} +template struct MoveOrCopyAssign<D7>; // expected-note {{here}} +template struct CopyAssign<D8>; // expected-note {{here}} +template struct MoveAssign<D8>; // expected-note {{here}} +template struct MoveOrCopyAssign<D8>; // expected-note {{here}} // -- a direct or virtual base that cannot be copied/moved struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}} @@ -136,7 +164,7 @@ template struct MoveAssign<E6>; // expected-note {{here}} namespace PR13381 { struct S { S &operator=(const S&); - S &operator=(const volatile S&) = delete; // expected-note{{deleted here}} + S &operator=(const volatile S&) volatile = delete; // expected-note{{deleted here}} }; struct T { volatile S s; // expected-note{{field 's' has a deleted copy assignment}} |