1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 2 3// Tests for implicit (non-)declaration of move constructor and 4// assignment: p9, p11, p20, p23. 5 6// This class, used as a member, allows to distinguish move from copy because 7// move operations are no-throw, copy operations aren't. 8struct ThrowingCopy { 9 ThrowingCopy() noexcept; 10 ThrowingCopy(ThrowingCopy &&) noexcept; 11 ThrowingCopy(const ThrowingCopy &) noexcept(false); 12 ThrowingCopy & operator =(ThrowingCopy &&) noexcept; 13 ThrowingCopy & operator =(const ThrowingCopy &) noexcept(false); 14}; 15 16struct HasCopyConstructor { 17 ThrowingCopy tc; 18 HasCopyConstructor() noexcept; 19 HasCopyConstructor(const HasCopyConstructor &) noexcept(false); 20}; 21 22struct HasCopyAssignment { 23 ThrowingCopy tc; 24 HasCopyAssignment() noexcept; 25 HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false); 26}; 27 28struct HasMoveConstructor { // expected-note {{implicit copy assignment}} 29 ThrowingCopy tc; 30 HasMoveConstructor() noexcept; 31 HasMoveConstructor(HasMoveConstructor &&) noexcept; 32}; 33 34struct HasMoveAssignment { // expected-note {{implicit copy constructor}} 35 ThrowingCopy tc; 36 HasMoveAssignment() noexcept; 37 HasMoveAssignment & operator =(HasMoveAssignment &&) noexcept; 38}; 39 40struct HasDestructor { 41 ThrowingCopy tc; 42 HasDestructor() noexcept; 43 ~HasDestructor() noexcept; 44}; 45 46void test_basic_exclusion() { 47 static_assert(!noexcept(HasCopyConstructor((HasCopyConstructor()))), ""); 48 HasCopyConstructor hcc; 49 static_assert(!noexcept(hcc = HasCopyConstructor()), ""); 50 51 static_assert(!noexcept(HasCopyAssignment((HasCopyAssignment()))), ""); 52 HasCopyAssignment hca; 53 static_assert(!noexcept(hca = HasCopyAssignment()), ""); 54 55 static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), ""); 56 HasMoveConstructor hmc; 57 hmc = HasMoveConstructor(); // expected-error {{selected deleted operator}} 58 59 (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}} 60 HasMoveAssignment hma; 61 static_assert(noexcept(hma = HasMoveAssignment()), ""); 62 63 static_assert(!noexcept(HasDestructor((HasDestructor()))), ""); 64 HasDestructor hd; 65 static_assert(!noexcept(hd = HasDestructor()), ""); 66} 67 68struct PrivateMove { 69 PrivateMove() noexcept; 70 PrivateMove(const PrivateMove &) noexcept(false); 71 PrivateMove & operator =(const PrivateMove &) noexcept(false); 72private: 73 PrivateMove(PrivateMove &&) noexcept; 74 PrivateMove & operator =(PrivateMove &&) noexcept; 75}; 76 77struct InheritsPrivateMove : PrivateMove {}; 78struct ContainsPrivateMove { 79 PrivateMove pm; 80}; 81 82struct PrivateDestructor { 83 PrivateDestructor() noexcept; 84 PrivateDestructor(const PrivateDestructor &) noexcept(false); 85 PrivateDestructor(PrivateDestructor &&) noexcept; 86private: 87 ~PrivateDestructor() noexcept; 88}; 89 90struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note {{explicitly marked deleted}} 91struct ContainsPrivateDestructor { // expected-note {{explicitly marked deleted}} 92 PrivateDestructor pd; 93}; 94 95struct NonTrivialCopyOnly { 96 NonTrivialCopyOnly() noexcept; 97 NonTrivialCopyOnly(const NonTrivialCopyOnly &) noexcept(false); 98 NonTrivialCopyOnly & operator =(const NonTrivialCopyOnly &) noexcept(false); 99}; 100 101struct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly {}; 102struct ContainsNonTrivialCopyOnly { 103 NonTrivialCopyOnly ntco; 104}; 105 106struct ContainsConst { 107 const int i; 108 ContainsConst() noexcept; 109 ContainsConst & operator =(ContainsConst &); // expected-note {{not viable}} 110}; 111 112struct ContainsRef { 113 int &i; 114 ContainsRef() noexcept; 115 ContainsRef & operator =(ContainsRef &); // expected-note {{not viable}} 116}; 117 118struct Base { 119 Base & operator =(Base &); 120}; 121struct DirectVirtualBase : virtual Base {}; // expected-note {{copy assignment operator) not viable}} 122struct IndirectVirtualBase : DirectVirtualBase {}; // expected-note {{copy assignment operator) not viable}} 123 124void test_deletion_exclusion() { 125 // FIXME: How to test the union thing? 126 127 static_assert(!noexcept(InheritsPrivateMove(InheritsPrivateMove())), ""); 128 static_assert(!noexcept(ContainsPrivateMove(ContainsPrivateMove())), ""); 129 InheritsPrivateMove ipm; 130 static_assert(!noexcept(ipm = InheritsPrivateMove()), ""); 131 ContainsPrivateMove cpm; 132 static_assert(!noexcept(cpm = ContainsPrivateMove()), ""); 133 134 (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to deleted constructor}} 135 (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to deleted constructor}} 136 137 static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), ""); 138 static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), ""); 139 InheritsNonTrivialCopyOnly intco; 140 static_assert(!noexcept(intco = InheritsNonTrivialCopyOnly()), ""); 141 ContainsNonTrivialCopyOnly cntco; 142 static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), ""); 143 144 ContainsConst cc; 145 cc = ContainsConst(); // expected-error {{no viable}} 146 147 ContainsRef cr; 148 cr = ContainsRef(); // expected-error {{no viable}} 149 150 DirectVirtualBase dvb; 151 dvb = DirectVirtualBase(); // expected-error {{no viable}} 152 153 IndirectVirtualBase ivb; 154 ivb = IndirectVirtualBase(); // expected-error {{no viable}} 155} 156 157struct ContainsRValueRef { 158 int&& ri; 159 ContainsRValueRef() noexcept; 160}; 161 162void test_contains_rref() { 163 (ContainsRValueRef(ContainsRValueRef())); 164} 165