summaryrefslogtreecommitdiff
path: root/clang/test/CXX/special
diff options
context:
space:
mode:
authorZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
committerZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
commit222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch)
tree7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CXX/special
parent3d206f03985b50beacae843d880bccdc91a9f424 (diff)
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CXX/special')
-rw-r--r--clang/test/CXX/special/class.copy/implicit-move-def.cpp117
-rw-r--r--clang/test/CXX/special/class.copy/implicit-move.cpp236
-rw-r--r--clang/test/CXX/special/class.copy/p11.0x.copy.cpp121
-rw-r--r--clang/test/CXX/special/class.copy/p11.0x.move.cpp164
-rw-r--r--clang/test/CXX/special/class.copy/p13-0x.cpp60
-rw-r--r--clang/test/CXX/special/class.copy/p15-0x.cpp41
-rw-r--r--clang/test/CXX/special/class.copy/p15-inclass.cpp42
-rw-r--r--clang/test/CXX/special/class.copy/p20.cpp46
-rw-r--r--clang/test/CXX/special/class.copy/p3.cpp27
-rw-r--r--clang/test/CXX/special/class.copy/p33-0x.cpp57
-rw-r--r--clang/test/CXX/special/class.copy/p8-cxx11.cpp48
-rw-r--r--clang/test/CXX/special/class.copy/p9.cpp44
-rw-r--r--clang/test/CXX/special/class.ctor/p1.cpp42
-rw-r--r--clang/test/CXX/special/class.ctor/p4-0x.cpp7
-rw-r--r--clang/test/CXX/special/class.ctor/p5-0x.cpp182
-rw-r--r--clang/test/CXX/special/class.ctor/p6-0x.cpp57
-rw-r--r--clang/test/CXX/special/class.dtor/p10-0x.cpp39
-rw-r--r--clang/test/CXX/special/class.dtor/p2-0x.cpp10
-rw-r--r--clang/test/CXX/special/class.dtor/p2.cpp7
-rw-r--r--clang/test/CXX/special/class.dtor/p3-0x.cpp177
-rw-r--r--clang/test/CXX/special/class.dtor/p5-0x.cpp104
-rw-r--r--clang/test/CXX/special/class.dtor/p9.cpp85
-rw-r--r--clang/test/CXX/special/class.free/p1.cpp11
-rw-r--r--clang/test/CXX/special/class.free/p6.cpp11
-rw-r--r--clang/test/CXX/special/class.inhctor/elsewhere.cpp57
-rw-r--r--clang/test/CXX/special/class.inhctor/p3.cpp48
-rw-r--r--clang/test/CXX/special/class.inhctor/p7.cpp29
-rw-r--r--clang/test/CXX/special/class.init/class.base.init/p8-0x.cpp62
-rw-r--r--clang/test/CXX/special/class.init/class.base.init/p9-0x.cpp36
-rw-r--r--clang/test/CXX/special/class.temporary/p1.cpp57
30 files changed, 2024 insertions, 0 deletions
diff --git a/clang/test/CXX/special/class.copy/implicit-move-def.cpp b/clang/test/CXX/special/class.copy/implicit-move-def.cpp
new file mode 100644
index 0000000..5c54aea
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/implicit-move-def.cpp
@@ -0,0 +1,117 @@
+// 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-ASSIGN %s
+// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-CTOR %s
+
+// construct
+
+struct E {
+ E();
+ E(E&&);
+};
+
+struct F {
+ F();
+ F(F&&);
+};
+
+struct G {
+ E e;
+};
+
+struct H : G {
+ F l;
+ E m;
+ F ar[2];
+};
+
+void f() {
+ H s;
+ // CHECK: call void @_ZN1HC1EOS_
+ H t(static_cast<H&&>(s));
+}
+
+
+// assign
+
+struct A {
+ A &operator =(A&&);
+};
+
+struct B {
+ B &operator =(B&&);
+};
+
+struct C {
+ A a;
+};
+
+struct D : C {
+ A a;
+ B b;
+ A ar[2];
+};
+
+void g() {
+ D d;
+ // CHECK: call {{.*}} @_ZN1DaSEOS_
+ d = D();
+}
+
+// PR10822
+struct I {
+ unsigned var[1];
+};
+
+// CHECK: define void @_Z1hv() nounwind {
+void h() {
+ I i;
+ // CHECK: call void @llvm.memcpy.
+ i = I();
+ // CHECK-NEXT: ret void
+}
+
+// PR10860
+struct Empty { };
+struct VirtualWithEmptyBase : Empty {
+ virtual void f();
+};
+
+// CHECK: define void @_Z25move_VirtualWithEmptyBaseR20VirtualWithEmptyBaseS0_
+void move_VirtualWithEmptyBase(VirtualWithEmptyBase &x, VirtualWithEmptyBase &y) {
+ // CHECK: call {{.*}} @_ZN20VirtualWithEmptyBaseaSEOS_
+ x = static_cast<VirtualWithEmptyBase&&>(y);
+ // CHECK-NEXT: ret void
+}
+
+// move assignment ops
+
+// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1DaSEOS_
+// CHECK-ASSIGN: call {{.*}} @_ZN1CaSEOS_
+// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_
+// CHECK-ASSIGN: call {{.*}} @_ZN1BaSEOS_
+// array loop
+// CHECK-ASSIGN: br i1
+// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_
+
+// VirtualWithEmptyBase move assignment operatpr
+// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN20VirtualWithEmptyBaseaSEOS_
+// CHECK-ASSIGN: store
+// CHECK-ASSIGN-NEXT: store
+// CHECK-ASSIGN-NOT: call
+// CHECK-ASSIGN: ret
+
+// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1CaSEOS_
+// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_
+
+// move ctors
+
+// CHECK-CTOR: define linkonce_odr {{.*}} @_ZN1HC2EOS_
+// CHECK-CTOR: call {{.*}} @_ZN1GC2EOS_
+// CHECK-CTOR: call {{.*}} @_ZN1FC1EOS_
+// CHECK-CTOR: call {{.*}} @_ZN1EC1EOS_
+// array loop
+// CHECK-CTOR: br i1
+// CHECK-CTOR: call {{.*}} @_ZN1FC1EOS_
+
+// CHECK-CTOR: define linkonce_odr {{.*}} @_ZN1GC2EOS_
+// CHECK-CTOR: call {{.*}} @_ZN1EC1EOS_
diff --git a/clang/test/CXX/special/class.copy/implicit-move.cpp b/clang/test/CXX/special/class.copy/implicit-move.cpp
new file mode 100644
index 0000000..3e9accf
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/implicit-move.cpp
@@ -0,0 +1,236 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Tests for implicit (non-)declaration of move constructor and
+// assignment: p9, p11, p20, p23.
+
+// This class, used as a member, allows to distinguish move from copy because
+// move operations are no-throw, copy operations aren't.
+struct ThrowingCopy {
+ ThrowingCopy() noexcept;
+ ThrowingCopy(ThrowingCopy &&) noexcept;
+ ThrowingCopy(const ThrowingCopy &) noexcept(false);
+ ThrowingCopy & operator =(ThrowingCopy &&) noexcept;
+ ThrowingCopy & operator =(const ThrowingCopy &) noexcept(false);
+};
+
+struct HasCopyConstructor {
+ ThrowingCopy tc;
+ HasCopyConstructor() noexcept;
+ HasCopyConstructor(const HasCopyConstructor &) noexcept(false);
+};
+
+struct HasCopyAssignment {
+ ThrowingCopy tc;
+ HasCopyAssignment() noexcept;
+ HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false);
+};
+
+struct HasMoveConstructor {
+ ThrowingCopy tc;
+ HasMoveConstructor() noexcept;
+ HasMoveConstructor(HasMoveConstructor &&) noexcept; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}}
+};
+
+struct HasMoveAssignment { // expected-note {{implicit copy constructor}}
+ ThrowingCopy tc;
+ HasMoveAssignment() noexcept;
+ HasMoveAssignment & operator =(HasMoveAssignment &&) noexcept;
+};
+
+struct HasDestructor {
+ ThrowingCopy tc;
+ HasDestructor() noexcept;
+ ~HasDestructor() noexcept;
+};
+
+void test_basic_exclusion() {
+ static_assert(!noexcept(HasCopyConstructor((HasCopyConstructor()))), "");
+ HasCopyConstructor hcc;
+ static_assert(!noexcept(hcc = HasCopyConstructor()), "");
+
+ static_assert(!noexcept(HasCopyAssignment((HasCopyAssignment()))), "");
+ HasCopyAssignment hca;
+ static_assert(!noexcept(hca = HasCopyAssignment()), "");
+
+ static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
+ HasMoveConstructor hmc;
+ hmc = HasMoveConstructor(); // expected-error {{selected implicitly-deleted copy assignment}}
+
+ (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
+ HasMoveAssignment hma;
+ static_assert(noexcept(hma = HasMoveAssignment()), "");
+
+ static_assert(!noexcept(HasDestructor((HasDestructor()))), "");
+ HasDestructor hd;
+ static_assert(!noexcept(hd = HasDestructor()), "");
+}
+
+struct PrivateMove {
+ PrivateMove() noexcept;
+ PrivateMove(const PrivateMove &) noexcept(false);
+ PrivateMove & operator =(const PrivateMove &) noexcept(false);
+private:
+ PrivateMove(PrivateMove &&) noexcept;
+ PrivateMove & operator =(PrivateMove &&) noexcept;
+};
+
+struct InheritsPrivateMove : PrivateMove {};
+struct ContainsPrivateMove {
+ PrivateMove pm;
+};
+
+struct PrivateDestructor {
+ PrivateDestructor() noexcept;
+ PrivateDestructor(const PrivateDestructor &) noexcept(false);
+ PrivateDestructor(PrivateDestructor &&) noexcept;
+private:
+ ~PrivateDestructor() noexcept;
+};
+
+struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
+struct ContainsPrivateDestructor {
+ PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}}
+};
+
+struct NonTrivialCopyOnly {
+ NonTrivialCopyOnly() noexcept;
+ NonTrivialCopyOnly(const NonTrivialCopyOnly &) noexcept(false);
+ NonTrivialCopyOnly & operator =(const NonTrivialCopyOnly &) noexcept(false);
+};
+
+struct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly {};
+struct ContainsNonTrivialCopyOnly {
+ NonTrivialCopyOnly ntco;
+};
+
+struct ContainsConst {
+ const int i;
+ ContainsConst() noexcept;
+ ContainsConst & operator =(ContainsConst &); // expected-note {{not viable}}
+};
+
+struct ContainsRef {
+ int &i;
+ ContainsRef() noexcept;
+ ContainsRef & operator =(ContainsRef &); // expected-note {{not viable}}
+};
+
+struct Base {
+ Base & operator =(Base &);
+};
+struct DirectVirtualBase : virtual Base {}; // expected-note {{copy assignment operator) not viable}}
+struct IndirectVirtualBase : DirectVirtualBase {}; // expected-note {{copy assignment operator) not viable}}
+
+void test_deletion_exclusion() {
+ // FIXME: How to test the union thing?
+
+ static_assert(!noexcept(InheritsPrivateMove(InheritsPrivateMove())), "");
+ static_assert(!noexcept(ContainsPrivateMove(ContainsPrivateMove())), "");
+ InheritsPrivateMove ipm;
+ static_assert(!noexcept(ipm = InheritsPrivateMove()), "");
+ ContainsPrivateMove cpm;
+ static_assert(!noexcept(cpm = ContainsPrivateMove()), "");
+
+ (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
+ (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
+
+ static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), "");
+ static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), "");
+ InheritsNonTrivialCopyOnly intco;
+ static_assert(!noexcept(intco = InheritsNonTrivialCopyOnly()), "");
+ ContainsNonTrivialCopyOnly cntco;
+ static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), "");
+
+ ContainsConst cc;
+ cc = ContainsConst(); // expected-error {{no viable}}
+
+ ContainsRef cr;
+ cr = ContainsRef(); // expected-error {{no viable}}
+
+ DirectVirtualBase dvb;
+ dvb = DirectVirtualBase(); // expected-error {{no viable}}
+
+ IndirectVirtualBase ivb;
+ ivb = IndirectVirtualBase(); // expected-error {{no viable}}
+}
+
+struct ContainsRValueRef {
+ int&& ri;
+ ContainsRValueRef() noexcept;
+};
+
+void test_contains_rref() {
+ (ContainsRValueRef(ContainsRValueRef()));
+}
+
+
+namespace DR1402 {
+ struct NonTrivialCopyCtor {
+ NonTrivialCopyCtor(const NonTrivialCopyCtor &);
+ };
+ struct NonTrivialCopyAssign {
+ NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
+ };
+
+ struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor {
+ NonTrivialCopyCtorVBase(NonTrivialCopyCtorVBase &&);
+ NonTrivialCopyCtorVBase &operator=(NonTrivialCopyCtorVBase &&) = default;
+ };
+ struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign {
+ NonTrivialCopyAssignVBase(NonTrivialCopyAssignVBase &&);
+ NonTrivialCopyAssignVBase &operator=(NonTrivialCopyAssignVBase &&) = default;
+ };
+
+ struct NonTrivialMoveAssign {
+ NonTrivialMoveAssign(NonTrivialMoveAssign&&);
+ NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
+ };
+ struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign {
+ NonTrivialMoveAssignVBase(NonTrivialMoveAssignVBase &&);
+ 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).
+ 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}}
+ };
+}
diff --git a/clang/test/CXX/special/class.copy/p11.0x.copy.cpp b/clang/test/CXX/special/class.copy/p11.0x.copy.cpp
new file mode 100644
index 0000000..b2b4f6a
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p11.0x.copy.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+struct NonTrivial {
+ NonTrivial(const NonTrivial&);
+};
+
+// A defaulted copy constructor for a class X is defined as deleted if X has:
+
+// -- a variant member with a non-trivial corresponding constructor
+union DeletedNTVariant {
+ NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant' is implicitly deleted because field 'NT' has a non-trivial copy constructor}}
+ DeletedNTVariant();
+};
+DeletedNTVariant DVa;
+DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy constructor}}
+
+struct DeletedNTVariant2 {
+ union {
+ NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant2' is implicitly deleted because field 'NT' has a non-trivial copy constructor}}
+ };
+ DeletedNTVariant2();
+};
+DeletedNTVariant2 DV2a;
+DeletedNTVariant2 DV2b(DV2a); // expected-error{{call to implicitly-deleted copy constructor}}
+
+// -- a non-static data member of class type M (or array thereof) that cannot be
+// copied because overload resolution results in an ambiguity or a function
+// that is deleted or inaccessible
+struct NoAccess {
+ NoAccess() = default;
+private:
+ NoAccess(const NoAccess&);
+
+ friend struct HasAccess;
+};
+
+struct HasNoAccess {
+ NoAccess NA; // expected-note{{copy constructor of 'HasNoAccess' is implicitly deleted because field 'NA' has an inaccessible copy constructor}}
+};
+HasNoAccess HNAa;
+HasNoAccess HNAb(HNAa); // expected-error{{call to implicitly-deleted copy constructor}}
+
+struct HasAccess {
+ NoAccess NA;
+};
+
+HasAccess HAa;
+HasAccess HAb(HAa);
+
+struct NonConst {
+ NonConst(NonConst&);
+};
+struct Ambiguity {
+ Ambiguity(const Ambiguity&);
+ Ambiguity(volatile Ambiguity&);
+};
+
+struct IsAmbiguous {
+ NonConst NC;
+ Ambiguity A; // expected-note 2{{copy constructor of 'IsAmbiguous' is implicitly deleted because field 'A' has multiple copy constructors}}
+ IsAmbiguous();
+};
+IsAmbiguous IAa;
+IsAmbiguous IAb(IAa); // expected-error{{call to implicitly-deleted copy constructor}}
+
+struct Deleted {
+ IsAmbiguous IA; // expected-note{{copy constructor of 'Deleted' is implicitly deleted because field 'IA' has a deleted copy constructor}}
+};
+Deleted Da;
+Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}}
+
+// -- 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
+struct AmbiguousCopyBase : Ambiguity { // expected-note 2{{copy constructor of 'AmbiguousCopyBase' is implicitly deleted because base class 'Ambiguity' has multiple copy constructors}}
+ NonConst NC;
+};
+extern AmbiguousCopyBase ACBa;
+AmbiguousCopyBase ACBb(ACBa); // expected-error {{deleted copy constructor}}
+
+struct DeletedCopyBase : AmbiguousCopyBase {}; // expected-note {{copy constructor of 'DeletedCopyBase' is implicitly deleted because base class 'AmbiguousCopyBase' has a deleted copy constructor}}
+extern DeletedCopyBase DCBa;
+DeletedCopyBase DCBb(DCBa); // expected-error {{deleted copy constructor}}
+
+struct InaccessibleCopyBase : NoAccess {}; // expected-note {{copy constructor of 'InaccessibleCopyBase' is implicitly deleted because base class 'NoAccess' has an inaccessible copy constructor}}
+extern InaccessibleCopyBase ICBa;
+InaccessibleCopyBase ICBb(ICBa); // expected-error {{deleted copy constructor}}
+
+// -- any direct or virtual base class or non-static data member of a type with
+// a destructor that is deleted or inaccessible
+struct NoAccessDtor {
+private:
+ ~NoAccessDtor();
+ friend struct HasAccessDtor;
+};
+
+struct HasNoAccessDtor {
+ NoAccessDtor NAD; // expected-note{{copy constructor of 'HasNoAccessDtor' is implicitly deleted because field 'NAD' has an inaccessible destructor}}
+ HasNoAccessDtor();
+ ~HasNoAccessDtor();
+};
+HasNoAccessDtor HNADa;
+HasNoAccessDtor HNADb(HNADa); // expected-error{{call to implicitly-deleted copy constructor}}
+
+struct HasAccessDtor {
+ NoAccessDtor NAD;
+};
+HasAccessDtor HADa;
+HasAccessDtor HADb(HADa);
+
+struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has an inaccessible destructor}}
+};
+extern HasNoAccessDtorBase HNADBa;
+HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
+
+// -- 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 &&'}}
+};
+RValue RVa;
+RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}}
diff --git a/clang/test/CXX/special/class.copy/p11.0x.move.cpp b/clang/test/CXX/special/class.copy/p11.0x.move.cpp
new file mode 100644
index 0000000..ff9478b
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p11.0x.move.cpp
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+struct NonTrivial {
+ NonTrivial(NonTrivial&&);
+};
+
+// A defaulted move constructor for a class X is defined as deleted if X has:
+
+// -- a variant member with a non-trivial corresponding constructor
+union DeletedNTVariant {
+ NonTrivial NT;
+ DeletedNTVariant(DeletedNTVariant&&);
+};
+DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
+
+struct DeletedNTVariant2 {
+ union {
+ NonTrivial NT;
+ };
+ DeletedNTVariant2(DeletedNTVariant2&&);
+};
+DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}}
+
+// -- a non-static data member of class type M (or array thereof) that cannot be
+// copied because overload resolution results in an ambiguity or a function
+// that is deleted or inaccessible
+struct NoAccess {
+ NoAccess() = default;
+private:
+ NoAccess(NoAccess&&);
+
+ friend struct HasAccess;
+};
+
+struct HasNoAccess {
+ NoAccess NA;
+ HasNoAccess(HasNoAccess&&);
+};
+HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
+
+struct HasAccess {
+ NoAccess NA;
+ HasAccess(HasAccess&&);
+};
+HasAccess::HasAccess(HasAccess&&) = default;
+
+struct Ambiguity {
+ Ambiguity(const Ambiguity&&);
+ Ambiguity(volatile Ambiguity&&);
+};
+
+struct IsAmbiguous {
+ Ambiguity A;
+ IsAmbiguous(IsAmbiguous&&);
+};
+IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}
+
+struct Deleted {
+ IsAmbiguous IA;
+ Deleted(Deleted&&);
+};
+Deleted::Deleted(Deleted&&) = 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
+struct AmbiguousMoveBase : Ambiguity {
+ AmbiguousMoveBase(AmbiguousMoveBase&&);
+};
+AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}
+
+struct DeletedMoveBase : AmbiguousMoveBase {
+ DeletedMoveBase(DeletedMoveBase&&);
+};
+DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}
+
+struct InaccessibleMoveBase : NoAccess {
+ InaccessibleMoveBase(InaccessibleMoveBase&&);
+};
+InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}
+
+// -- any direct or virtual base class or non-static data member of a type with
+// a destructor that is deleted or inaccessible
+struct NoAccessDtor {
+ NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}
+private:
+ ~NoAccessDtor();
+ friend struct HasAccessDtor;
+};
+
+struct HasNoAccessDtor {
+ NoAccessDtor NAD;
+ HasNoAccessDtor(HasNoAccessDtor&&);
+};
+HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}
+
+struct HasAccessDtor {
+ NoAccessDtor NAD;
+ HasAccessDtor(HasAccessDtor&&);
+};
+HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;
+
+struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}
+};
+extern HasNoAccessDtorBase HNADBa;
+HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
+
+// The restriction on rvalue reference members applies to only the copy
+// constructor.
+struct RValue {
+ int &&ri = 1;
+ RValue(RValue&&);
+};
+RValue::RValue(RValue&&) = default;
+
+// -- a non-static data member or direct or virtual base class with a type that
+// does not have a move constructor and is not trivially copyable
+struct CopyOnly {
+ CopyOnly(const CopyOnly&);
+};
+
+struct NonMove {
+ CopyOnly CO;
+ NonMove(NonMove&&);
+};
+NonMove::NonMove(NonMove&&) = default; // ok under DR1402
+
+struct Moveable {
+ Moveable();
+ Moveable(Moveable&&);
+};
+
+struct HasMove {
+ Moveable M;
+ HasMove(HasMove&&);
+};
+HasMove::HasMove(HasMove&&) = default;
+
+namespace DR1402 {
+ struct member {
+ member();
+ member(const member&);
+ member& operator=(const member&);
+ ~member();
+ };
+
+ struct A {
+ member m_;
+
+ A() = default;
+ A(const A&) = default;
+ A& operator=(const A&) = default;
+ A(A&&) = default;
+ A& operator=(A&&) = default;
+ ~A() = default;
+ };
+
+ // ok, A's explicitly-defaulted move operations copy m_.
+ void f() {
+ A a, b(a), c(static_cast<A&&>(a));
+ a = b;
+ b = static_cast<A&&>(c);
+ }
+}
diff --git a/clang/test/CXX/special/class.copy/p13-0x.cpp b/clang/test/CXX/special/class.copy/p13-0x.cpp
new file mode 100644
index 0000000..0a9aa62
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p13-0x.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// If the implicitly-defined constructor would satisfy the requirements of a
+// constexpr constructor, the implicitly-defined constructor is constexpr.
+struct Constexpr1 {
+ constexpr Constexpr1() : n(0) {}
+ int n;
+};
+constexpr Constexpr1 c1a = Constexpr1(Constexpr1()); // ok
+constexpr Constexpr1 c1b = Constexpr1(Constexpr1(c1a)); // ok
+
+struct Constexpr2 {
+ Constexpr1 ce1;
+ constexpr Constexpr2() = default;
+ constexpr Constexpr2(const Constexpr2 &o) : ce1(o.ce1) {}
+ // no move constructor
+};
+
+constexpr Constexpr2 c2a = Constexpr2(Constexpr2()); // ok
+constexpr Constexpr2 c2b = Constexpr2(Constexpr2(c2a)); // ok
+
+struct Constexpr3 {
+ Constexpr2 ce2;
+ // all special constructors are constexpr, move ctor calls ce2's copy ctor
+};
+
+constexpr Constexpr3 c3a = Constexpr3(Constexpr3()); // ok
+constexpr Constexpr3 c3b = Constexpr3(Constexpr3(c3a)); // ok
+
+struct NonConstexprCopy {
+ constexpr NonConstexprCopy() = default;
+ NonConstexprCopy(const NonConstexprCopy &);
+ constexpr NonConstexprCopy(NonConstexprCopy &&) = default;
+
+ int n = 42;
+};
+
+NonConstexprCopy::NonConstexprCopy(const NonConstexprCopy &) = default; // expected-note {{here}}
+
+constexpr NonConstexprCopy ncc1 = NonConstexprCopy(NonConstexprCopy()); // ok
+constexpr NonConstexprCopy ncc2 = ncc1; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
+
+struct NonConstexprDefault {
+ NonConstexprDefault() = default;
+ constexpr NonConstexprDefault(int n) : n(n) {}
+ int n;
+};
+struct Constexpr4 {
+ NonConstexprDefault ncd;
+};
+
+constexpr NonConstexprDefault ncd = NonConstexprDefault(NonConstexprDefault(1));
+constexpr Constexpr4 c4a = { ncd };
+constexpr Constexpr4 c4b = Constexpr4(c4a);
+constexpr Constexpr4 c4c = Constexpr4(static_cast<Constexpr4&&>(const_cast<Constexpr4&>(c4b)));
+
+struct Constexpr5Base {};
+struct Constexpr5 : Constexpr5Base { constexpr Constexpr5() {} };
+constexpr Constexpr5 ce5move = Constexpr5();
+constexpr Constexpr5 ce5copy = ce5move;
diff --git a/clang/test/CXX/special/class.copy/p15-0x.cpp b/clang/test/CXX/special/class.copy/p15-0x.cpp
new file mode 100644
index 0000000..fff8844
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p15-0x.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+namespace PR10622 {
+ struct foo {
+ const int first;
+ foo(const foo&) = default;
+ };
+ void find_or_insert(const foo& __obj) {
+ foo x(__obj);
+ }
+
+ struct bar : foo {
+ bar(const bar&) = default;
+ };
+ void test_bar(const bar &obj) {
+ bar obj2(obj);
+ }
+}
+
+namespace PR11418 {
+ template<typename T>
+ T may_throw() {
+ return T();
+ }
+
+ template<typename T> T &&declval() noexcept;
+
+ struct NonPOD {
+ NonPOD();
+ NonPOD(const NonPOD &) noexcept;
+ NonPOD(NonPOD &&) noexcept;
+ };
+
+ struct X {
+ NonPOD np = may_throw<NonPOD>();
+ };
+
+ static_assert(noexcept(declval<X>()), "noexcept isn't working at all");
+ static_assert(noexcept(X(declval<X&>())), "copy constructor can't throw");
+ static_assert(noexcept(X(declval<X>())), "move constructor can't throw");
+}
diff --git a/clang/test/CXX/special/class.copy/p15-inclass.cpp b/clang/test/CXX/special/class.copy/p15-inclass.cpp
new file mode 100644
index 0000000..c4f8eaf
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p15-inclass.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+namespace PR11418 {
+ struct NonPOD {
+ NonPOD();
+ NonPOD(const NonPOD &);
+ NonPOD(NonPOD &&);
+ };
+
+ struct X {
+ NonPOD np;
+ int a = 17;
+ };
+
+ void check_copy(X x) {
+ X x2(x);
+ }
+
+ void check_move(X x) {
+ X x3(static_cast<X&&>(x));
+ }
+
+ // CHECK: define linkonce_odr void @_ZN7PR114181XC2EOS0_
+ // CHECK-NOT: 17
+ // CHECK: call void @_ZN7PR114186NonPODC1EOS0_
+ // CHECK-NOT: 17
+ // CHECK: load i32*
+ // CHECK-NOT: 17
+ // CHECK: store i32
+ // CHECK-NOT: 17
+ // CHECK: ret
+
+ // CHECK: define linkonce_odr void @_ZN7PR114181XC2ERKS0_
+ // CHECK-NOT: 17
+ // CHECK: call void @_ZN7PR114186NonPODC1ERKS0_
+ // CHECK-NOT: 17
+ // CHECK: load i32*
+ // CHECK-NOT: 17
+ // CHECK: store i32
+ // CHECK-NOT: 17
+ // CHECK: ret
+}
diff --git a/clang/test/CXX/special/class.copy/p20.cpp b/clang/test/CXX/special/class.copy/p20.cpp
new file mode 100644
index 0000000..8dfb7ca
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p20.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct ConstCopy {
+ ConstCopy();
+ ConstCopy &operator=(const ConstCopy&);
+};
+
+struct NonConstCopy {
+ NonConstCopy();
+ NonConstCopy &operator=(NonConstCopy&);
+};
+
+struct VirtualInheritsNonConstCopy : virtual NonConstCopy {
+ VirtualInheritsNonConstCopy();
+ VirtualInheritsNonConstCopy &operator=(const VirtualInheritsNonConstCopy&);
+};
+
+struct ImplicitNonConstCopy1 : NonConstCopy { // expected-note{{the implicit copy assignment operator}}
+ ImplicitNonConstCopy1();
+};
+
+struct ImplicitNonConstCopy2 { // expected-note{{the implicit copy assignment operator}}
+ ImplicitNonConstCopy2();
+ NonConstCopy ncc;
+};
+
+struct ImplicitNonConstCopy3 { // expected-note{{the implicit copy assignment operator}}
+ ImplicitNonConstCopy3();
+ NonConstCopy ncc_array[2][3];
+};
+
+struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy {
+ ImplicitNonConstCopy4();
+};
+
+void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1,
+ const ImplicitNonConstCopy2 &cincc2,
+ const ImplicitNonConstCopy3 &cincc3,
+ const ImplicitNonConstCopy4 &cincc4,
+ const VirtualInheritsNonConstCopy &vincc) {
+ (void)sizeof(ImplicitNonConstCopy1() = cincc1); // expected-error{{no viable overloaded '='}}
+ (void)sizeof(ImplicitNonConstCopy2() = cincc2); // expected-error{{no viable overloaded '='}}
+ (void)sizeof(ImplicitNonConstCopy3() = cincc3); // expected-error{{no viable overloaded '='}}
+ (void)sizeof(ImplicitNonConstCopy4() = cincc4); // okay
+ (void)sizeof(VirtualInheritsNonConstCopy() = vincc);
+}
diff --git a/clang/test/CXX/special/class.copy/p3.cpp b/clang/test/CXX/special/class.copy/p3.cpp
new file mode 100644
index 0000000..3d87266
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p3.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+// PR6141
+template<typename T>
+struct X {
+ X();
+ template<typename U> X(X<U>);
+ X(const X<T>&);
+};
+
+void f(X<int>) { }
+
+struct Y : X<int> { };
+struct Z : X<float> { };
+
+// CHECK: define i32 @main()
+int main() {
+ // CHECK: call void @_ZN1YC1Ev
+ // CHECK: call void @_ZN1XIiEC1ERKS0_
+ // CHECK: call void @_Z1f1XIiE
+ f(Y());
+ // CHECK: call void @_ZN1ZC1Ev
+ // CHECK: call void @_ZN1XIfEC1ERKS0_
+ // CHECK: call void @_ZN1XIiEC1IfEES_IT_E
+ // CHECK: call void @_Z1f1XIiE
+ f(Z());
+}
diff --git a/clang/test/CXX/special/class.copy/p33-0x.cpp b/clang/test/CXX/special/class.copy/p33-0x.cpp
new file mode 100644
index 0000000..b66e19a
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p33-0x.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++11 -fsyntax-only -verify %s
+class X {
+ X(const X&);
+
+public:
+ X();
+ X(X&&);
+};
+
+X return_by_move(int i, X x) {
+ X x2;
+ if (i == 0)
+ return x;
+ else if (i == 1)
+ return x2;
+ else
+ return x;
+}
+
+void throw_move_only(X x) {
+ X x2;
+ throw x;
+ throw x2;
+}
+
+namespace PR10142 {
+ struct X {
+ X();
+ X(X&&);
+ X(const X&) = delete; // expected-note 2{{function has been explicitly marked deleted here}}
+ };
+
+ void f(int i) {
+ X x;
+ try {
+ X x2;
+ if (i)
+ throw x2; // okay
+ throw x; // expected-error{{call to deleted constructor of 'PR10142::X'}}
+ } catch (...) {
+ }
+ }
+
+ template<typename T>
+ void f2(int i) {
+ T x;
+ try {
+ T x2;
+ if (i)
+ throw x2; // okay
+ throw x; // expected-error{{call to deleted constructor of 'PR10142::X'}}
+ } catch (...) {
+ }
+ }
+
+ template void f2<X>(int); // expected-note{{in instantiation of function template specialization 'PR10142::f2<PR10142::X>' requested here}}
+}
diff --git a/clang/test/CXX/special/class.copy/p8-cxx11.cpp b/clang/test/CXX/special/class.copy/p8-cxx11.cpp
new file mode 100644
index 0000000..02e6cd1
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p8-cxx11.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify
+
+// C++98 [class.copy]p5 / C++11 [class.copy]p8.
+
+// The implicitly-declared copy constructor for a class X will have the form
+// X::X(const X&)
+// if [every direct subobject] has a copy constructor whose first parameter is
+// of type 'const volatile[opt] T &'. Otherwise, it will have the form
+// X::X(X&)
+
+struct ConstCopy {
+ ConstCopy(const ConstCopy &);
+};
+
+struct NonConstCopy {
+ NonConstCopy(NonConstCopy &);
+};
+
+struct DeletedConstCopy {
+ DeletedConstCopy(const DeletedConstCopy &) = delete;
+};
+
+struct DeletedNonConstCopy {
+ DeletedNonConstCopy(DeletedNonConstCopy &) = delete;
+};
+
+struct ImplicitlyDeletedConstCopy {
+ ImplicitlyDeletedConstCopy(ImplicitlyDeletedConstCopy &&);
+};
+
+
+struct A : ConstCopy {};
+struct B : NonConstCopy { ConstCopy a; };
+struct C : ConstCopy { NonConstCopy a; };
+struct D : DeletedConstCopy {};
+struct E : DeletedNonConstCopy {};
+struct F { ImplicitlyDeletedConstCopy a; };
+struct G : virtual B {};
+
+struct Test {
+ friend A::A(const A &);
+ friend B::B(B &);
+ friend C::C(C &);
+ friend D::D(const D &);
+ friend E::E(E &);
+ friend F::F(const F &);
+ friend G::G(G &);
+};
diff --git a/clang/test/CXX/special/class.copy/p9.cpp b/clang/test/CXX/special/class.copy/p9.cpp
new file mode 100644
index 0000000..77ab19e
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p9.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct ConstCopy {
+ ConstCopy();
+ ConstCopy(const ConstCopy&);
+};
+
+struct NonConstCopy {
+ NonConstCopy();
+ NonConstCopy(NonConstCopy&);
+};
+
+struct VirtualInheritsNonConstCopy : virtual NonConstCopy {
+ VirtualInheritsNonConstCopy();
+ VirtualInheritsNonConstCopy(const VirtualInheritsNonConstCopy&);
+};
+
+struct ImplicitNonConstCopy1 : NonConstCopy { // expected-note {{candidate constructor}}
+ ImplicitNonConstCopy1(); // expected-note {{candidate constructor}}
+};
+
+struct ImplicitNonConstCopy2 { // expected-note {{candidate constructor}}
+ ImplicitNonConstCopy2(); // expected-note {{candidate constructor}}
+ NonConstCopy ncc;
+};
+
+struct ImplicitNonConstCopy3 { // expected-note {{candidate constructor}}
+ ImplicitNonConstCopy3(); // expected-note {{candidate constructor}}
+ NonConstCopy ncc_array[2][3];
+};
+
+struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { // expected-note {{candidate constructor}}
+ ImplicitNonConstCopy4(); // expected-note {{candidate constructor}}
+};
+
+void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1,
+ const ImplicitNonConstCopy2 &cincc2,
+ const ImplicitNonConstCopy3 &cincc3,
+ const ImplicitNonConstCopy4 &cincc4) {
+ (void)sizeof(ImplicitNonConstCopy1(cincc1)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy1' to 'ImplicitNonConstCopy1'}}
+ (void)sizeof(ImplicitNonConstCopy2(cincc2)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy2' to 'ImplicitNonConstCopy2'}}
+ (void)sizeof(ImplicitNonConstCopy3(cincc3)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy3' to 'ImplicitNonConstCopy3'}}
+ (void)sizeof(ImplicitNonConstCopy4(cincc4)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy4' to 'ImplicitNonConstCopy4'}}
+}
diff --git a/clang/test/CXX/special/class.ctor/p1.cpp b/clang/test/CXX/special/class.ctor/p1.cpp
new file mode 100644
index 0000000..9500a7d
--- /dev/null
+++ b/clang/test/CXX/special/class.ctor/p1.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X0 {
+ struct type { };
+
+ X0();
+ X0(int);
+ (X0)(float);
+ X0 (f0)(int);
+ X0 (f0)(type);
+
+ X0 f1();
+ X0 f1(double);
+};
+
+X0::X0() { }
+(X0::X0)(int) { }
+
+X0 (X0::f0)(int) { return X0(); }
+
+template<typename T>
+struct X1 {
+ struct type { };
+
+ X1<T>();
+ X1<T>(int);
+ (X1<T>)(float);
+ X1(float, float);
+ (X1)(double);
+ X1<T> (f0)(int);
+ X1<T> (f0)(type);
+ X1 (f1)(int);
+ X1 (f1)(type);
+
+ template<typename U> X1(U);
+ X1 f2();
+ X1 f2(int);
+};
+
+template<typename T> X1<T>::X1() { }
+template<typename T> (X1<T>::X1)(double) { }
+template<typename T> X1<T> X1<T>::f1(int) { return 0; }
+template<typename T> X1<T> (X1<T>::f1)(type) { return 0; }
diff --git a/clang/test/CXX/special/class.ctor/p4-0x.cpp b/clang/test/CXX/special/class.ctor/p4-0x.cpp
new file mode 100644
index 0000000..509beb4
--- /dev/null
+++ b/clang/test/CXX/special/class.ctor/p4-0x.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// A constructor shall not be declared with a ref-qualifier.
+struct X {
+ X() &; // expected-error{{ref-qualifier '&' is not allowed on a constructor}}
+ X(int) &&; // expected-error{{ref-qualifier '&&' is not allowed on a constructor}}
+};
diff --git a/clang/test/CXX/special/class.ctor/p5-0x.cpp b/clang/test/CXX/special/class.ctor/p5-0x.cpp
new file mode 100644
index 0000000..694ab5b
--- /dev/null
+++ b/clang/test/CXX/special/class.ctor/p5-0x.cpp
@@ -0,0 +1,182 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+struct DefaultedDefCtor1 {};
+struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; };
+struct DeletedDefCtor { DeletedDefCtor() = delete; DeletedDefCtor(int); }; // expected-note {{explicitly marked deleted here}}
+class PrivateDefCtor { PrivateDefCtor() = default; public: PrivateDefCtor(int); };
+struct DeletedDtor { ~DeletedDtor() = delete; }; // expected-note 4{{explicitly marked deleted here}}
+class PrivateDtor { ~PrivateDtor() = default; };
+class Friend {
+ Friend() = default; ~Friend() = default;
+ friend struct NotDeleted6c;
+ friend struct NotDeleted7i;
+ friend struct NotDeleted7j;
+ friend struct NotDeleted7k;
+};
+struct UserProvidedDefCtor { UserProvidedDefCtor() {} };
+int n;
+
+
+// A defaulted default constructor for a class X is defined as deleted if:
+
+// - X is a union-like class that has a variant member with a non-trivial
+// default constructor,
+union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of union 'Deleted1a' is implicitly deleted because field 'u' has a non-trivial default constructor}}
+Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}}
+union NotDeleted1a { DefaultedDefCtor1 nu; };
+NotDeleted1a nd1a;
+union NotDeleted1b { DefaultedDefCtor2 nu; };
+NotDeleted1b nd1b;
+
+// - any non-static data member with no brace-or-equal-initializer is of
+// reference type,
+class Deleted2a {
+ Deleted2a() = default; // expected-note 4{{implicitly deleted here}}
+ int &a; // expected-note 4{{because field 'a' of reference type 'int &' would not be initialized}}
+};
+Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted2b {
+ int &&b; // expected-note {{default constructor of 'Deleted2b' is implicitly deleted because field 'b' of reference type 'int &&' would not be initialized}}
+};
+Deleted2b d2b; // expected-error {{deleted default constructor}}
+class NotDeleted2a { int &a = n; };
+NotDeleted2a nd2a;
+class NotDeleted2b { int &a = error; }; // expected-error {{undeclared identifier}}
+NotDeleted2b nd2b;
+class NotDeleted2c { int &&a = 0; };
+NotDeleted2c nd2c;
+
+// - any non-variant non-static data member of const qualified type (or array
+// thereof) with no brace-or-equal-initializer does not have a user-provided
+// default constructor,
+class Deleted3a { const int a; }; // expected-note {{because field 'a' of const-qualified type 'const int' would not be initialized}} \
+ expected-warning {{does not declare any constructor}} \
+ expected-note {{will never be initialized}}
+Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}}
+class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1' would not be initialized}}
+Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}}
+class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor2' would not be initialized}}
+Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}}
+class NotDeleted3a { const int a = 0; };
+NotDeleted3a nd3a;
+class NotDeleted3b { const DefaultedDefCtor1 a[42] = {}; };
+NotDeleted3b nd3b;
+class NotDeleted3c { const DefaultedDefCtor2 a = DefaultedDefCtor2(); };
+NotDeleted3c nd3c;
+union NotDeleted3d { const int a; int b; };
+NotDeleted3d nd3d;
+union NotDeleted3e { const DefaultedDefCtor1 a[42]; int b; };
+NotDeleted3e nd3e;
+union NotDeleted3f { const DefaultedDefCtor2 a; int b; };
+NotDeleted3f nd3f;
+struct NotDeleted3g { union { const int a; int b; }; };
+NotDeleted3g nd3g;
+
+// - X is a union and all of its variant members are of const-qualified type (or
+// array thereof),
+union Deleted4a {
+ const int a;
+ const int b;
+ const UserProvidedDefCtor c; // expected-note {{because field 'c' has a non-trivial default constructor}}
+};
+Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}}
+union NotDeleted4a { const int a; int b; };
+NotDeleted4a nd4a;
+
+// - X is a non-union class and all members of any anonymous union member are of
+// const-qualified type (or array thereof),
+struct Deleted5a {
+ union { const int a; }; // expected-note {{because all data members of an anonymous union member are const-qualified}}
+ union { int b; };
+};
+Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}}
+struct NotDeleted5a { union { const int a; int b; }; union { const int c; int d; }; };
+NotDeleted5a nd5a;
+
+// - any direct or virtual base class, or non-static data member with no
+// brace-or-equal-initializer, has class type M (or array thereof) and either
+// M has no default constructor or overload resolution as applied to M's default
+// constructor results in an ambiguity or in a function that is deleted or
+// inaccessible from the defaulted default constructor, or
+struct Deleted6a : Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}}
+Deleted6a d6a; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted6b : virtual Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}}
+Deleted6b d6b; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted6c { Deleted2a a; }; // expected-note {{because field 'a' has a deleted default constructor}}
+Deleted6c d6c; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted6d { DeletedDefCtor a; }; // expected-note {{because field 'a' has a deleted default constructor}}
+Deleted6d d6d; // expected-error {{implicitly-deleted default constructor}}
+struct NotDeleted6a { DeletedDefCtor a = 0; };
+NotDeleted6a nd6a;
+struct Deleted6e { PrivateDefCtor a; }; // expected-note {{because field 'a' has an inaccessible default constructor}}
+Deleted6e d6e; // expected-error {{implicitly-deleted default constructor}}
+struct NotDeleted6b { PrivateDefCtor a = 0; };
+NotDeleted6b nd6b;
+struct NotDeleted6c { Friend a; };
+NotDeleted6c nd6c;
+
+// - any direct or virtual base class or non-static data member has a type with
+// a destructor that is deleted or inaccessible from the defaulted default
+// constructor.
+struct Deleted7a : DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}}
+Deleted7a d7a; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted7b : virtual DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}}
+Deleted7b d7b; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted7c { DeletedDtor a; }; // expected-note {{because field 'a' has a deleted destructor}}
+Deleted7c d7c; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{because field 'a' has a deleted destructor}}
+Deleted7d d7d; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted7e : PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}}
+Deleted7e d7e; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted7f : virtual PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}}
+Deleted7f d7f; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted7g { PrivateDtor a; }; // expected-note {{field 'a' has an inaccessible destructor}}
+Deleted7g d7g; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{field 'a' has an inaccessible destructor}}
+Deleted7h d7h; // expected-error {{implicitly-deleted default constructor}}
+struct NotDeleted7i : Friend {};
+NotDeleted7i d7i;
+struct NotDeleted7j : virtual Friend {};
+NotDeleted7j d7j;
+struct NotDeleted7k { Friend a; };
+NotDeleted7k d7k;
+
+
+class Trivial { static const int n = 42; };
+static_assert(__has_trivial_constructor(Trivial), "Trivial is nontrivial");
+
+// A default constructor is trivial if it is not user-provided and if:
+class NonTrivialDefCtor1 { NonTrivialDefCtor1(); };
+static_assert(!__has_trivial_constructor(NonTrivialDefCtor1), "NonTrivialDefCtor1 is trivial");
+
+// - its class has no virtual functions (10.3) and no virtual base classes (10.1), and
+class NonTrivialDefCtor2 { virtual void f(); };
+static_assert(!__has_trivial_constructor(NonTrivialDefCtor2), "NonTrivialDefCtor2 is trivial");
+class NonTrivialDefCtor3 : virtual Trivial {};
+static_assert(!__has_trivial_constructor(NonTrivialDefCtor3), "NonTrivialDefCtor3 is trivial");
+
+// - no non-static data member of its class has a brace-or-equal-initializer, and
+class NonTrivialDefCtor4 { int m = 52; };
+static_assert(!__has_trivial_constructor(NonTrivialDefCtor4), "NonTrivialDefCtor4 is trivial");
+
+// - all the direct base classes of its class have trivial default constructors, and
+class NonTrivialDefCtor5 : NonTrivialDefCtor1 {};
+static_assert(!__has_trivial_constructor(NonTrivialDefCtor5), "NonTrivialDefCtor5 is trivial");
+
+// - for all the non-static data members of its class that are of class type (or array thereof), each such class
+// has a trivial default constructor.
+class NonTrivialDefCtor6 { NonTrivialDefCtor1 t; };
+static_assert(!__has_trivial_constructor(NonTrivialDefCtor6), "NonTrivialDefCtor5 is trivial");
+
+// Otherwise, the default constructor is non-trivial.
+class Trivial2 { Trivial2() = delete; };
+static_assert(__has_trivial_constructor(Trivial2), "Trivial2 is trivial");
+
+class Trivial3 { Trivial3() = default; };
+static_assert(__has_trivial_constructor(Trivial3), "Trivial3 is trivial");
+
+template<typename T> class Trivial4 { Trivial4() = default; };
+static_assert(__has_trivial_constructor(Trivial4<int>), "Trivial4 is trivial");
+
+template<typename T> class Trivial5 { Trivial5() = delete; };
+static_assert(__has_trivial_constructor(Trivial5<int>), "Trivial5 is trivial");
diff --git a/clang/test/CXX/special/class.ctor/p6-0x.cpp b/clang/test/CXX/special/class.ctor/p6-0x.cpp
new file mode 100644
index 0000000..8c8800f
--- /dev/null
+++ b/clang/test/CXX/special/class.ctor/p6-0x.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+// Implicitly-defined default constructors are constexpr if the implicit
+// definition would be.
+struct NonConstexpr1 { // expected-note {{here}}
+ int a;
+};
+struct NonConstexpr2 { // expected-note {{here}}
+ NonConstexpr1 nl;
+};
+struct NonConstexpr2a : NonConstexpr1 { };
+constexpr NonConstexpr1 nc1 = NonConstexpr1(); // ok, does not call constructor
+constexpr NonConstexpr2 nc2 = NonConstexpr2(); // ok, does not call constructor
+constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // ok, does not call constructor
+constexpr int nc2_a = NonConstexpr2().nl.a; // ok
+constexpr int nc2a_a = NonConstexpr2a().a; // ok
+struct Helper {
+ friend constexpr NonConstexpr1::NonConstexpr1(); // expected-error {{follows non-constexpr declaration}}
+ friend constexpr NonConstexpr2::NonConstexpr2(); // expected-error {{follows non-constexpr declaration}}
+};
+
+struct Constexpr1 {};
+constexpr Constexpr1 c1 = Constexpr1(); // ok
+struct NonConstexpr3 : virtual Constexpr1 {}; // expected-note {{struct with virtual base}} expected-note {{declared here}}
+constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{non-literal type 'const NonConstexpr3'}}
+
+struct Constexpr2 {
+ int a = 0;
+};
+constexpr Constexpr2 c2 = Constexpr2(); // ok
+
+int n;
+struct Member {
+ Member() : a(n) {}
+ constexpr Member(int&a) : a(a) {}
+ int &a;
+};
+struct NonConstexpr4 { // expected-note {{here}}
+ Member m;
+};
+constexpr NonConstexpr4 nc4 = NonConstexpr4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4'}}
+struct Constexpr3 {
+ constexpr Constexpr3() : m(n) {}
+ Member m;
+};
+constexpr Constexpr3 c3 = Constexpr3(); // ok
+struct Constexpr4 {
+ Constexpr3 m;
+};
+constexpr Constexpr4 c4 = Constexpr4(); // ok
+
+
+// This rule breaks some legal C++98 programs!
+struct A {}; // expected-note {{here}}
+struct B {
+ friend A::A(); // expected-error {{non-constexpr declaration of 'A' follows constexpr declaration}}
+};
diff --git a/clang/test/CXX/special/class.dtor/p10-0x.cpp b/clang/test/CXX/special/class.dtor/p10-0x.cpp
new file mode 100644
index 0000000..e10afb5
--- /dev/null
+++ b/clang/test/CXX/special/class.dtor/p10-0x.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// PR10127/N3031
+struct A { ~A(); };
+struct B {};
+template<typename T>
+void b(const T *x, const A *y) {
+ x->~decltype(T())();
+ x->~decltype(*x)(); // expected-error{{the type of object expression ('const int') does not match the type being destroyed ('decltype(*x)' (aka 'const int &')) in pseudo-destructor expression}} \
+ expected-error{{no member named '~const struct A &' in 'A'}}
+ x->~decltype(int())(); // expected-error{{no member named '~int' in 'A'}}
+
+ y->~decltype(*y)(); // expected-error{{destructor type 'decltype(*y)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
+ y->~decltype(T())(); // expected-error{{destructor type 'decltype(T())' in object destruction expression does not match the type 'const A' of the object being destroyed}}
+ y->~decltype(A())();
+}
+template void b(const int*, const A*); // expected-note{{in instantiation of function template specialization 'b<int>' requested here}}
+template void b(const A*,const A*); // expected-note{{in instantiation of function template specialization 'b<A>' requested here}}
+void a(const A *x, int i, int *pi) {
+ x->~decltype(A())();
+ x->~decltype(*x)(); // expected-error{{destructor type 'decltype(*x)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
+ x->~decltype()(); // expected-error{{expected expression}}
+ x->~decltype(B())(); // expected-error{{destructor type 'decltype(B())' (aka 'B') in object destruction expression does not match the type 'const A' of the object being destroyed}}
+ x->~decltype(x)(); // expected-error{{destructor type 'decltype(x)' (aka 'const A *') in object destruction expression does not match the type 'const A' of the object being destroyed}}
+ // this last one could be better, mentioning that the nested-name-specifier could be removed or a type name after the ~
+ x->::A::~decltype(*x)(); // expected-error{{expected a class name after '~' to name a destructor}}
+ y->~decltype(A())(); // expected-error{{use of undeclared identifier 'y'}}
+
+ typedef int *intp;
+ i->~decltype(int())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}}
+ i.~decltype(int())();
+ i->~decltype(intp())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}} \
+ expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
+ i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
+ pi->~decltype(int())();
+ pi.~decltype(int())(); // expected-error{{the type of object expression ('int *') does not match the type being destroyed ('decltype(int())' (aka 'int')) in pseudo-destructor expression}}
+ pi.~decltype(intp())();
+ pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
+}
diff --git a/clang/test/CXX/special/class.dtor/p2-0x.cpp b/clang/test/CXX/special/class.dtor/p2-0x.cpp
new file mode 100644
index 0000000..c7b1b58
--- /dev/null
+++ b/clang/test/CXX/special/class.dtor/p2-0x.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// A destructor shall not be declared with a ref-qualifier.
+struct X {
+ ~X() &; // expected-error{{ref-qualifier '&' is not allowed on a destructor}}
+};
+
+struct Y {
+ ~Y() &&; // expected-error{{ref-qualifier '&&' is not allowed on a destructor}}
+};
diff --git a/clang/test/CXX/special/class.dtor/p2.cpp b/clang/test/CXX/special/class.dtor/p2.cpp
new file mode 100644
index 0000000..b05c992
--- /dev/null
+++ b/clang/test/CXX/special/class.dtor/p2.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5548
+struct A {~A();};
+void a(const A* x) {
+ x->~A();
+}
diff --git a/clang/test/CXX/special/class.dtor/p3-0x.cpp b/clang/test/CXX/special/class.dtor/p3-0x.cpp
new file mode 100644
index 0000000..44bf5aa
--- /dev/null
+++ b/clang/test/CXX/special/class.dtor/p3-0x.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+ ~A();
+};
+
+struct B {
+ ~B() throw(int);
+};
+
+struct C {
+ B b;
+ ~C() {}
+};
+
+struct D {
+ ~D() noexcept(false);
+};
+
+struct E {
+ D d;
+ ~E() {}
+};
+
+void foo() {
+ A a;
+ C c;
+ E e;
+ // CHECK: invoke {{.*}} @_ZN1ED1Ev
+ // CHECK: invoke {{.*}} @_ZN1CD1Ev
+ // CHECK: call {{.*}} @_ZN1AD1Ev
+}
+
+struct F {
+ D d;
+ ~F();
+};
+F::~F() noexcept(false) {}
+
+struct G {
+ D d;
+ ~G();
+};
+G::~G() {}
+
+struct H {
+ B b;
+ ~H();
+};
+H::~H() throw(int) {}
+
+struct I {
+ B b;
+ ~I();
+};
+I::~I() {}
+
+// Template variants.
+
+template <typename T>
+struct TA {
+ ~TA();
+};
+
+template <typename T>
+struct TB {
+ ~TB() throw(int);
+};
+
+template <typename T>
+struct TC {
+ TB<T> b;
+ ~TC() {}
+};
+
+template <typename T>
+struct TD {
+ ~TD() noexcept(false);
+};
+
+template <typename T>
+struct TE {
+ TD<T> d;
+ ~TE() {}
+};
+
+void tfoo() {
+ TA<int> a;
+ TC<int> c;
+ TE<int> e;
+ // CHECK: invoke {{.*}} @_ZN2TEIiED1Ev
+ // CHECK: invoke {{.*}} @_ZN2TCIiED1Ev
+ // CHECK: call {{.*}} @_ZN2TAIiED1Ev
+}
+
+template <typename T>
+struct TF {
+ TD<T> d;
+ ~TF();
+};
+template <typename T>
+TF<T>::~TF() noexcept(false) {}
+
+template <typename T>
+struct TG {
+ TD<T> d;
+ ~TG();
+};
+template <typename T>
+TG<T>::~TG() {}
+
+template <typename T>
+struct TH {
+ TB<T> b;
+ ~TH();
+};
+template <typename T>
+TH<T>::~TH() {}
+
+void tinst() {
+ TF<int> f;
+ TG<int> g;
+ TH<int> h;
+}
+// CHECK: define linkonce_odr {{.*}} @_ZN2THIiED1Ev
+// CHECK: _ZTIi
+// CHECK: __cxa_call_unexpected
+
+struct VX
+{ virtual ~VX() {} };
+
+struct VY : VX
+{ virtual ~VY() {} };
+
+template<typename T>
+struct TVY : VX
+{ virtual ~TVY() {} };
+
+
+struct VA {
+ B b;
+ virtual ~VA() {}
+};
+
+struct VB : VA
+{ virtual ~VB() {} };
+
+template<typename T>
+struct TVB : VA
+{ virtual ~TVB() {} };
+
+void tinst2() {
+ TVY<int> tvy;
+ TVB<int> tvb;
+}
+
+template <typename T>
+struct Sw {
+ T t;
+ ~Sw() {}
+};
+
+void tsw() {
+ Sw<int> swi;
+ Sw<B> swb;
+}
+// CHECK-NOT: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}} nounwind
+// CHECK: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}}
+// CHECK: _ZTIi
+// CHECK: __cxa_call_unexpected
+// CHECK: define linkonce_odr {{.*}} @_ZN2SwIiED1Ev({{.*}} nounwind
+
+template <typename T>
+struct TVC : VX
+{ virtual ~TVC(); };
+template <typename T>
+TVC<T>::~TVC() {}
diff --git a/clang/test/CXX/special/class.dtor/p5-0x.cpp b/clang/test/CXX/special/class.dtor/p5-0x.cpp
new file mode 100644
index 0000000..dbfa004
--- /dev/null
+++ b/clang/test/CXX/special/class.dtor/p5-0x.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+
+struct NonTrivDtor {
+ ~NonTrivDtor();
+};
+struct DeletedDtor {
+ ~DeletedDtor() = delete; // expected-note 5 {{deleted here}}
+};
+class InaccessibleDtor {
+ ~InaccessibleDtor() = default;
+};
+
+// A defaulted destructor for a class X is defined as deleted if:
+
+// -- X is a union-like class that has a variant member with a non-trivial
+// destructor.
+union A1 {
+ A1();
+ NonTrivDtor n; // expected-note {{destructor of union 'A1' is implicitly deleted because field 'n' has a non-trivial destructor}}
+};
+A1 a1; // expected-error {{deleted function}}
+struct A2 {
+ A2();
+ union {
+ NonTrivDtor n; // expected-note {{because field 'n' has a non-trivial destructor}}
+ };
+};
+A2 a2; // expected-error {{deleted function}}
+union A3 {
+ A3();
+ NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}}
+};
+A3 a3; // expected-error {{deleted function}}
+struct A4 {
+ A4();
+ union {
+ NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}}
+ };
+};
+A4 a4; // expected-error {{deleted function}}
+
+// -- any of the non-static data members has class type M (or array thereof) and
+// M has a deleted or inaccessible destructor.
+struct B1 {
+ B1();
+ DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}}
+};
+B1 b1; // expected-error {{deleted function}}
+struct B2 {
+ B2();
+ InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}}
+};
+B2 b2; // expected-error {{deleted function}}
+struct B3 {
+ B3();
+ DeletedDtor a[4]; // expected-note {{because field 'a' has a deleted destructor}}
+};
+B3 b3; // expected-error {{deleted function}}
+struct B4 {
+ B4();
+ InaccessibleDtor a[4]; // expected-note {{because field 'a' has an inaccessible destructor}}
+};
+B4 b4; // expected-error {{deleted function}}
+union B5 {
+ B5();
+ // FIXME: Describe the anonymous union member better than ''.
+ union { // expected-note {{because field '' has a deleted destructor}}
+ DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}}
+ };
+};
+B5 b5; // expected-error {{deleted function}}
+union B6 {
+ B6();
+ union { // expected-note {{because field '' has a deleted destructor}}
+ InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}}
+ };
+};
+B6 b6; // expected-error {{deleted function}}
+
+// -- any direct or virtual base class has a deleted or inaccessible destructor.
+struct C1 : DeletedDtor { C1(); } c1; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}}
+struct C2 : InaccessibleDtor { C2(); } c2; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}}
+struct C3 : virtual DeletedDtor { C3(); } c3; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}}
+struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}}
+
+// -- for a virtual destructor, lookup of the non-array deallocation function
+// results in an ambiguity or a function that is deleted or inaccessible.
+class D1 {
+ void operator delete(void*);
+public:
+ virtual ~D1() = default;
+} d1; // ok
+struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+ // implicitly-virtual destructor
+} d2; // expected-error {{deleted function}}
+struct D3 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+ virtual ~D3() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}}
+ void operator delete(void*, double = 0.0);
+ void operator delete(void*, char = 0);
+} d3; // expected-error {{deleted function}}
+struct D4 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+ virtual ~D4() = default; // expected-note {{implicitly deleted here}}
+ void operator delete(void*) = delete;
+} d4; // expected-error {{deleted function}}
diff --git a/clang/test/CXX/special/class.dtor/p9.cpp b/clang/test/CXX/special/class.dtor/p9.cpp
new file mode 100644
index 0000000..8b76a15
--- /dev/null
+++ b/clang/test/CXX/special/class.dtor/p9.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef typeof(sizeof(int)) size_t;
+
+// PR7803
+namespace test0 {
+ class A {
+ public:
+ static void operator delete(void *p) {};
+ virtual ~A();
+ };
+
+ class B : protected A {
+ public:
+ ~B();
+ };
+
+ class C : protected B {
+ public:
+ using B::operator delete;
+ ~C();
+ };
+
+ // Shouldn't have an error.
+ C::~C() {}
+}
+
+namespace test1 {
+ class A {
+ public:
+ static void operator delete(void *p) {}; // expected-note {{member 'operator delete' declared here}}
+ virtual ~A();
+ };
+
+ class B : protected A {
+ public:
+ static void operator delete(void *, size_t) {}; // expected-note {{member 'operator delete' declared here}}
+ ~B();
+ };
+
+ class C : protected B {
+ public:
+ using A::operator delete;
+ using B::operator delete;
+
+ ~C();
+ };
+
+ C::~C() {} // expected-error {{multiple suitable 'operator delete' functions in 'C'}}
+}
+
+// ...at the point of definition of a virtual destructor...
+namespace test2 {
+ struct A {
+ virtual ~A();
+ static void operator delete(void*, const int &);
+ };
+
+ struct B {
+ virtual ~B();
+ static void operator delete(void*, const int &); // expected-note {{declared here}}
+ };
+ B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}}
+
+ struct CBase { virtual ~CBase(); };
+ struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}}
+ static void operator delete(void*, const int &); // expected-note {{declared here}}
+ };
+ void test() {
+ C c; // expected-note {{first required here}}
+ }
+}
+
+// PR7346
+namespace test3 {
+ struct A {
+ virtual ~A();
+ static void operator delete(void*, const int &);
+ };
+
+ struct B : A {
+ virtual ~B() {}
+ static void operator delete(void*);
+ };
+}
diff --git a/clang/test/CXX/special/class.free/p1.cpp b/clang/test/CXX/special/class.free/p1.cpp
new file mode 100644
index 0000000..5c0240b
--- /dev/null
+++ b/clang/test/CXX/special/class.free/p1.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+#include <stddef.h>
+
+struct A {
+ void *operator new(size_t) {
+ return this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
+ }
+ void *operator new[](size_t) {
+ return this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
+ }
+};
diff --git a/clang/test/CXX/special/class.free/p6.cpp b/clang/test/CXX/special/class.free/p6.cpp
new file mode 100644
index 0000000..fc4b2ae
--- /dev/null
+++ b/clang/test/CXX/special/class.free/p6.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+#include <stddef.h>
+
+struct A {
+ void operator delete(void*) {
+ (void)this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
+ }
+ void operator delete[](void*) {
+ (void)this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
+ }
+};
diff --git a/clang/test/CXX/special/class.inhctor/elsewhere.cpp b/clang/test/CXX/special/class.inhctor/elsewhere.cpp
new file mode 100644
index 0000000..09fd3d5
--- /dev/null
+++ b/clang/test/CXX/special/class.inhctor/elsewhere.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// Tests related to constructor inheriting, but not specified in [class.inhctor]
+
+// [namespace.udecl]p8:
+// A using-declaration for a class member shall be a member-declaration.
+
+struct B1 {
+ B1(int);
+};
+
+using B1::B1; // expected-error {{using declaration can not refer to class member}} expected-error {{not supported}}
+
+// C++0x [namespace.udecl]p10:
+// A using-declaration is a declaration and can therefore be used repeatedly
+// where (and only where) multiple declarations are allowed.
+
+struct I1 : B1 {
+ using B1::B1; // expected-note {{previous using declaration}} expected-error {{not supported}}
+ using B1::B1; // expected-error {{redeclaration of using decl}} expected-error {{not supported}}
+};
+
+// C++0x [namespace.udecl]p3:
+// In a using declaration used as a member-declaration, the nested-name-
+// specifier shall name a base class of the class being defined.
+// If such a using-declaration names a constructor, the nested-name-specifier
+// shall name a direct base class of the class being defined.
+
+struct D1 : I1 {
+ using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} expected-error {{not supported}}
+};
+
+template<typename T> struct A {};
+
+template<typename T> struct B : A<bool>, A<char> {
+ using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}} expected-error {{not supported}}
+};
+B<bool> bb;
+B<char> bc;
+B<double> bd; // expected-note {{here}}
+
+template<typename T> struct C : A<T> {
+ using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}} expected-error {{not supported}}
+};
+C<bool> cb;
+C<char> cc; // expected-note {{here}}
+
+template<typename T> struct D : A<T> {};
+template<typename T> struct E : D<T> {
+ using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}} expected-error {{not supported}}
+};
+E<bool> eb; // expected-note {{here}}
+
+template<typename T> struct F : D<bool> {
+ using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} expected-error {{not supported}}
+};
+F<bool> fb; // expected-note {{here}}
diff --git a/clang/test/CXX/special/class.inhctor/p3.cpp b/clang/test/CXX/special/class.inhctor/p3.cpp
new file mode 100644
index 0000000..d7093fb
--- /dev/null
+++ b/clang/test/CXX/special/class.inhctor/p3.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+struct B1 {
+ B1(int);
+ B1(int, int);
+};
+struct D1 : B1 {
+ using B1::B1; // expected-error {{not supported}}
+};
+D1 d1a(1), d1b(1, 1);
+
+D1 fd1() { return 1; }
+
+struct B2 {
+ explicit B2(int, int = 0, int = 0);
+};
+struct D2 : B2 { // expected-note 2 {{candidate constructor}}
+ using B2::B2; // expected-error {{not supported}}
+};
+D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);
+
+D2 fd2() { return 1; } // expected-error {{no viable conversion}}
+
+struct B3 {
+ B3(void*); // expected-note {{inherited from here}}
+};
+struct D3 : B3 { // expected-note 2 {{candidate constructor}}
+ using B3::B3; // expected-note {{candidate constructor (inherited)}} expected-error {{not supported}}
+};
+D3 fd3() { return 1; } // expected-error {{no viable conversion}}
+
+template<typename T> struct T1 : B1 {
+ using B1::B1; // expected-error {{not supported}}
+};
+template<typename T> struct T2 : T1<T> {
+ using T1<int>::T1; // expected-error {{not supported}}
+};
+template<typename T> struct T3 : T1<int> {
+ using T1<T>::T1; // expected-error {{not supported}}
+};
+struct U {
+ friend T1<int>::T1(int);
+ friend T1<int>::T1(int, int);
+ friend T2<int>::T2(int);
+ friend T2<int>::T2(int, int);
+ friend T3<int>::T3(int);
+ friend T3<int>::T3(int, int);
+};
diff --git a/clang/test/CXX/special/class.inhctor/p7.cpp b/clang/test/CXX/special/class.inhctor/p7.cpp
new file mode 100644
index 0000000..bfaa3ac
--- /dev/null
+++ b/clang/test/CXX/special/class.inhctor/p7.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// Straight from the standard
+struct B1 {
+ B1(int); // expected-note {{previous constructor}} expected-note {{conflicting constructor}}
+};
+struct B2 {
+ B2(int); // expected-note {{conflicting constructor}}
+};
+struct D1 : B1, B2 {
+ using B1::B1; // expected-note {{inherited here}} expected-error {{not supported}}
+ using B2::B2; // expected-error {{already inherited constructor with the same signature}} expected-error {{not supported}}
+};
+struct D2 : B1, B2 {
+ using B1::B1; // expected-error {{not supported}}
+ using B2::B2; // expected-error {{not supported}}
+ D2(int);
+};
+
+template<typename T> struct B3 {
+ B3(T); // expected-note {{previous constructor}}
+};
+template<typename T> struct B4 : B3<T>, B1 {
+ B4();
+ using B3<T>::B3; // expected-note {{inherited here}} expected-error {{not supported}}
+ using B1::B1; // expected-error {{already inherited}} expected-error {{not supported}}
+};
+B4<char> b4c;
+B4<int> b4i; // expected-note {{here}}
diff --git a/clang/test/CXX/special/class.init/class.base.init/p8-0x.cpp b/clang/test/CXX/special/class.init/class.base.init/p8-0x.cpp
new file mode 100644
index 0000000..a108533
--- /dev/null
+++ b/clang/test/CXX/special/class.init/class.base.init/p8-0x.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int n;
+struct S {
+ int &a; // expected-note 2{{here}}
+ int &b = n;
+
+ union {
+ const int k = 42;
+ };
+
+ S() {} // expected-error {{constructor for 'S' must explicitly initialize the reference member 'a'}}
+ S(int) : a(n) {} // ok
+ S(char) : b(n) {} // expected-error {{constructor for 'S' must explicitly initialize the reference member 'a'}}
+ S(double) : a(n), b(n) {} // ok
+} s(0);
+
+union U {
+ int a = 0; // desired-note 5 {{previous initialization is here}}
+ char b = 'x';
+
+ // FIXME: these should all be rejected
+ U() {} // desired-error {{initializing multiple members of union}}
+ U(int) : a(1) {} // desired-error {{initializing multiple members of union}}
+ U(char) : b('y') {} // desired-error {{initializing multiple members of union}}
+ // this expected note should be removed & the note should appear on the
+ // declaration of 'a' when this set of cases is handled correctly.
+ U(double) : a(1), // expected-note{{previous initialization is here}} desired-error {{initializing multiple members of union}}
+ b('y') {} // expected-error{{initializing multiple members of union}}
+};
+
+// PR10954: variant members do not acquire an implicit initializer.
+namespace VariantMembers {
+ struct NoDefaultCtor {
+ NoDefaultCtor(int);
+ };
+ union V {
+ NoDefaultCtor ndc;
+ int n;
+
+ V() {}
+ V(int n) : n(n) {}
+ V(int n, bool) : ndc(n) {}
+ };
+ struct K {
+ union {
+ NoDefaultCtor ndc;
+ int n;
+ };
+ K() {}
+ K(int n) : n(n) {}
+ K(int n, bool) : ndc(n) {}
+ };
+ struct Nested {
+ Nested() {}
+ union {
+ struct {
+ NoDefaultCtor ndc;
+ };
+ };
+ };
+}
diff --git a/clang/test/CXX/special/class.init/class.base.init/p9-0x.cpp b/clang/test/CXX/special/class.init/class.base.init/p9-0x.cpp
new file mode 100644
index 0000000..ca5e807
--- /dev/null
+++ b/clang/test/CXX/special/class.init/class.base.init/p9-0x.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++11 %s -O1 -emit-llvm -o - | FileCheck %s
+
+struct S {
+ int n = 10;
+ int m = 2 * n;
+
+ S() {}
+ S(int a) : n(a) {}
+ S(int a, int b) : n(a), m(b) {}
+
+ struct T {
+ T *that = this;
+ };
+};
+
+template<typename T>
+struct U {
+ T *r = &q;
+ T q = 42;
+ U *p = this;
+};
+
+S a;
+// CHECK: @a = {{.*}} { i32 10, i32 20 }
+
+S b(5);
+// CHECK: @b = {{.*}} { i32 5, i32 10 }
+
+S c(3, 9);
+// CHECK: @c = {{.*}} { i32 3, i32 9 }
+
+S::T d;
+// CHECK: @d = {{.*}} { {{.*}} @d }
+
+U<S> e;
+// CHECK: @e = {{.*}} { {{.*}} { i32 42, i32 84 }, {{.*}} @e }
diff --git a/clang/test/CXX/special/class.temporary/p1.cpp b/clang/test/CXX/special/class.temporary/p1.cpp
new file mode 100644
index 0000000..4f6ac0a
--- /dev/null
+++ b/clang/test/CXX/special/class.temporary/p1.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+namespace test0 {
+ struct A {
+ A() = default;
+ int x;
+ int y;
+
+ A(const A&) = delete; // expected-note {{function has been explicitly marked deleted here}}
+ };
+
+ void foo(...);
+
+ void test() {
+ A a;
+ foo(a); // expected-error {{call to deleted constructor of 'test0::A'}}
+ }
+}
+
+namespace test1 {
+ struct A {
+ A() = default;
+ int x;
+ int y;
+
+ private:
+ A(const A&) = default; // expected-note {{declared private here}}
+ };
+
+ void foo(...);
+
+ void test() {
+ A a;
+ foo(a); // expected-error {{calling a private constructor of class 'test1::A'}}
+ }
+}
+
+// Don't enforce this in an unevaluated context.
+namespace test2 {
+ struct A {
+ A(const A&) = delete; // expected-note {{marked deleted here}}
+ };
+
+ typedef char one[1];
+ typedef char two[2];
+
+ one &meta(bool);
+ two &meta(...);
+
+ void a(A &a) {
+ char check[sizeof(meta(a)) == 2 ? 1 : -1];
+ }
+
+ void b(A &a) {
+ meta(a); // expected-error {{call to deleted constructor}}
+ }
+}