summaryrefslogtreecommitdiffstats
path: root/test/CXX/special/class.copy
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
committerdim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
commit952eddef9aff85b1e92626e89baaf7a360e2ac85 (patch)
treedf8df0b0067b381eab470a3b8f28d14a552a6340 /test/CXX/special/class.copy
parentea266cad53e3d49771fa38103913d3ec7a166694 (diff)
downloadFreeBSD-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.cpp2
-rw-r--r--test/CXX/special/class.copy/implicit-move.cpp147
-rw-r--r--test/CXX/special/class.copy/p11.0x.copy.cpp8
-rw-r--r--test/CXX/special/class.copy/p11.0x.move.cpp21
-rw-r--r--test/CXX/special/class.copy/p12-0x.cpp4
-rw-r--r--test/CXX/special/class.copy/p23-cxx11.cpp38
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}}
OpenPOWER on IntegriCloud