| // RUN: %clang_cc1 -std=c++2b -fsyntax-only -fcxx-exceptions -verify=expected,cxx20_2b %s |
| // RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected,cxx20_2b %s |
| // RUN: %clang_cc1 -std=c++17 -fsyntax-only -fcxx-exceptions -verify=expected,cxx11_17 %s |
| // RUN: %clang_cc1 -std=c++14 -fsyntax-only -fcxx-exceptions -verify=expected,cxx11_17 %s |
| // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fcxx-exceptions -verify=expected,cxx11_17 %s |
| |
| namespace test_delete_function { |
| struct A1 { |
| A1(); |
| A1(const A1 &); |
| A1(A1 &&) = delete; // expected-note {{'A1' has been explicitly marked deleted here}} |
| }; |
| A1 test1() { |
| A1 a; |
| return a; // expected-error {{call to deleted constructor of 'test_delete_function::A1'}} |
| } |
| |
| struct A2 { |
| A2(); |
| A2(const A2 &); |
| |
| private: |
| A2(A2 &&); // expected-note {{declared private here}} |
| }; |
| A2 test2() { |
| A2 a; |
| return a; // expected-error {{calling a private constructor of class 'test_delete_function::A2'}} |
| } |
| |
| struct C {}; |
| |
| struct B1 { |
| B1(C &); |
| B1(C &&) = delete; // expected-note {{'B1' has been explicitly marked deleted here}} |
| }; |
| B1 test3() { |
| C c; |
| return c; // expected-error {{conversion function from 'test_delete_function::C' to 'test_delete_function::B1' invokes a deleted function}} |
| } |
| |
| struct B2 { |
| B2(C &); |
| |
| private: |
| B2(C &&); // expected-note {{declared private here}} |
| }; |
| B2 test4() { |
| C c; |
| return c; // expected-error {{calling a private constructor of class 'test_delete_function::B2'}} |
| } |
| } // namespace test_delete_function |
| |
| // In C++20, implicitly movable entity can be rvalue reference to non-volatile |
| // automatic object. |
| namespace test_implicitly_movable_rvalue_ref { |
| struct A1 { |
| A1(A1 &&); |
| A1(const A1 &) = delete; // cxx11_17-note {{'A1' has been explicitly marked deleted here}} |
| }; |
| A1 test1(A1 &&a) { |
| return a; // cxx11_17-error {{call to deleted constructor of 'test_implicitly_movable_rvalue_ref::A1'}} |
| } |
| |
| struct A2 { |
| A2(A2 &&); |
| |
| private: |
| A2(const A2 &); // cxx11_17-note {{declared private here}} |
| }; |
| A2 test2(A2 &&a) { |
| return a; // cxx11_17-error {{calling a private constructor of class 'test_implicitly_movable_rvalue_ref::A2'}} |
| } |
| |
| struct B1 { |
| B1(const B1 &); |
| B1(B1 &&) = delete; // cxx20_2b-note {{'B1' has been explicitly marked deleted here}} |
| }; |
| B1 test3(B1 &&b) { |
| return b; // cxx20_2b-error {{call to deleted constructor of 'test_implicitly_movable_rvalue_ref::B1'}} |
| } |
| |
| struct B2 { |
| B2(const B2 &); |
| |
| private: |
| B2(B2 &&); // cxx20_2b-note {{declared private here}} |
| }; |
| B2 test4(B2 &&b) { |
| return b; // cxx20_2b-error {{calling a private constructor of class 'test_implicitly_movable_rvalue_ref::B2'}} |
| } |
| } // namespace test_implicitly_movable_rvalue_ref |
| |
| // In C++20, operand of throw-expression can be function parameter or |
| // catch-clause parameter. |
| namespace test_throw_parameter { |
| void func(); |
| |
| struct A1 { |
| A1(const A1 &); |
| A1(A1 &&) = delete; // cxx20_2b-note {{'A1' has been explicitly marked deleted here}} |
| // expected-note@-1 {{'A1' has been explicitly marked deleted here}} |
| }; |
| void test1() { |
| try { |
| func(); |
| } catch (A1 a) { |
| throw a; // cxx20_2b-error {{call to deleted constructor of 'test_throw_parameter::A1'}} |
| } |
| } |
| |
| struct A2 { |
| A2(const A2 &); |
| |
| private: |
| A2(A2 &&); // cxx20_2b-note {{declared private here}} |
| }; |
| void test2() { |
| try { |
| func(); |
| } catch (A2 a) { |
| throw a; // cxx20_2b-error {{calling a private constructor of class 'test_throw_parameter::A2'}} |
| } |
| } |
| |
| void test3(A1 a) try { |
| func(); |
| } catch (...) { |
| throw a; // expected-error {{call to deleted constructor of 'test_throw_parameter::A1'}} |
| } |
| } // namespace test_throw_parameter |
| |
| // In C++20, during the first overload resolution, the selected function no |
| // need to be a constructor. |
| namespace test_non_ctor_conversion { |
| class C {}; |
| |
| struct A1 { |
| operator C() &&; |
| operator C() const & = delete; // cxx11_17-note {{'operator C' has been explicitly marked deleted here}} |
| }; |
| C test1() { |
| A1 a; |
| return a; // cxx11_17-error {{conversion function from 'test_non_ctor_conversion::A1' to 'test_non_ctor_conversion::C' invokes a deleted function}} |
| } |
| |
| struct A2 { |
| operator C() &&; |
| |
| private: |
| operator C() const &; // cxx11_17-note {{declared private here}} |
| }; |
| C test2() { |
| A2 a; |
| return a; // cxx11_17-error {{'operator C' is a private member of 'test_non_ctor_conversion::A2'}} |
| } |
| |
| struct B1 { |
| operator C() const &; |
| operator C() && = delete; // cxx20_2b-note {{'operator C' has been explicitly marked deleted here}} |
| }; |
| C test3() { |
| B1 b; |
| return b; // cxx20_2b-error {{conversion function from 'test_non_ctor_conversion::B1' to 'test_non_ctor_conversion::C' invokes a deleted function}} |
| } |
| |
| struct B2 { |
| operator C() const &; |
| |
| private: |
| operator C() &&; // cxx20_2b-note {{declared private here}} |
| }; |
| C test4() { |
| B2 b; |
| return b; // cxx20_2b-error {{'operator C' is a private member of 'test_non_ctor_conversion::B2'}} |
| } |
| } // namespace test_non_ctor_conversion |
| |
| // In C++20, during the first overload resolution, the first parameter of the |
| // selected function no need to be an rvalue reference to the object's type. |
| namespace test_ctor_param_rvalue_ref { |
| struct A1; |
| struct A2; |
| struct B1; |
| struct B2; |
| |
| struct NeedRvalueRef { |
| NeedRvalueRef(A1 &&); |
| NeedRvalueRef(A2 &&); |
| NeedRvalueRef(B1 &&); |
| NeedRvalueRef(B2 &&); |
| }; |
| struct NeedValue { |
| NeedValue(A1); // cxx11_17-note 2 {{passing argument to parameter here}} |
| NeedValue(A2); |
| NeedValue(B1); // cxx20_2b-note 2 {{passing argument to parameter here}} |
| NeedValue(B2); |
| }; |
| |
| struct A1 { |
| A1(); |
| A1(A1 &&); |
| A1(const A1 &) = delete; // cxx11_17-note 3 {{'A1' has been explicitly marked deleted here}} |
| }; |
| NeedValue test_1_1() { |
| // not rvalue reference |
| // same type |
| A1 a; |
| return a; // cxx11_17-error {{call to deleted constructor of 'test_ctor_param_rvalue_ref::A1'}} |
| } |
| class DerivedA1 : public A1 {}; |
| A1 test_1_2() { |
| // rvalue reference |
| // not same type |
| DerivedA1 a; |
| return a; // cxx11_17-error {{call to deleted constructor of 'test_ctor_param_rvalue_ref::A1'}} |
| } |
| NeedValue test_1_3() { |
| // not rvalue reference |
| // not same type |
| DerivedA1 a; |
| return a; // cxx11_17-error {{call to deleted constructor of 'test_ctor_param_rvalue_ref::A1'}} |
| } |
| |
| struct A2 { |
| A2(); |
| A2(A2 &&); |
| |
| private: |
| A2(const A2 &); // cxx11_17-note 3 {{declared private here}} |
| }; |
| NeedValue test_2_1() { |
| // not rvalue reference |
| // same type |
| A2 a; |
| return a; // cxx11_17-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::A2'}} |
| } |
| class DerivedA2 : public A2 {}; |
| A2 test_2_2() { |
| // rvalue reference |
| // not same type |
| DerivedA2 a; |
| return a; // cxx11_17-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::A2'}} |
| } |
| NeedValue test_2_3() { |
| // not rvalue reference |
| // not same type |
| DerivedA2 a; |
| return a; // cxx11_17-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::A2'}} |
| } |
| |
| struct B1 { |
| B1(); |
| B1(const B1 &); |
| B1(B1 &&) = delete; // cxx20_2b-note 3 {{'B1' has been explicitly marked deleted here}} |
| }; |
| NeedValue test_3_1() { |
| // not rvalue reference |
| // same type |
| B1 b; |
| return b; // cxx20_2b-error {{call to deleted constructor of 'test_ctor_param_rvalue_ref::B1'}} |
| } |
| class DerivedB1 : public B1 {}; |
| B1 test_3_2() { |
| // rvalue reference |
| // not same type |
| DerivedB1 b; |
| return b; // cxx20_2b-error {{call to deleted constructor of 'test_ctor_param_rvalue_ref::B1'}} |
| } |
| NeedValue test_3_3() { |
| // not rvalue reference |
| // not same type |
| DerivedB1 b; |
| return b; // cxx20_2b-error {{call to deleted constructor of 'test_ctor_param_rvalue_ref::B1'}} |
| } |
| |
| struct B2 { |
| B2(); |
| B2(const B2 &); |
| |
| private: |
| B2(B2 &&); // cxx20_2b-note 3 {{declared private here}} |
| }; |
| NeedValue test_4_1() { |
| // not rvalue reference |
| // same type |
| B2 b; |
| return b; // cxx20_2b-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::B2'}} |
| } |
| class DerivedB2 : public B2 {}; |
| B2 test_4_2() { |
| // rvalue reference |
| // not same type |
| DerivedB2 b; |
| return b; // cxx20_2b-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::B2'}} |
| } |
| NeedValue test_4_3() { |
| // not rvalue reference |
| // not same type |
| DerivedB2 b; |
| return b; // cxx20_2b-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::B2'}} |
| } |
| } // namespace test_ctor_param_rvalue_ref |
| |
| namespace test_lvalue_ref_is_not_moved_from { |
| |
| struct Target {}; |
| // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable}} |
| // expected-note@-2 {{candidate constructor (the implicit move constructor) not viable}} |
| // cxx11_17-note@-3 {{candidate constructor (the implicit copy constructor) not viable}} |
| // cxx11_17-note@-4 {{candidate constructor (the implicit move constructor) not viable}} |
| |
| struct CopyOnly { |
| CopyOnly(CopyOnly&&) = delete; // cxx20_2b-note {{has been explicitly marked deleted here}} |
| CopyOnly(CopyOnly&); |
| operator Target() && = delete; // cxx20_2b-note {{has been explicitly marked deleted here}} |
| operator Target() &; |
| }; |
| |
| struct MoveOnly { |
| MoveOnly(MoveOnly&&); // expected-note {{copy constructor is implicitly deleted because}} |
| // cxx11_17-note@-1 {{copy constructor is implicitly deleted because}} |
| operator Target() &&; // expected-note {{candidate function not viable}} |
| // cxx11_17-note@-1 {{candidate function not viable}} |
| }; |
| |
| extern CopyOnly copyonly; |
| extern MoveOnly moveonly; |
| |
| CopyOnly t1() { |
| CopyOnly& r = copyonly; |
| return r; |
| } |
| |
| CopyOnly t2() { |
| CopyOnly&& r = static_cast<CopyOnly&&>(copyonly); |
| return r; // cxx20_2b-error {{call to deleted constructor}} |
| } |
| |
| MoveOnly t3() { |
| MoveOnly& r = moveonly; |
| return r; // expected-error {{call to implicitly-deleted copy constructor}} |
| } |
| |
| MoveOnly t4() { |
| MoveOnly&& r = static_cast<MoveOnly&&>(moveonly); |
| return r; // cxx11_17-error {{call to implicitly-deleted copy constructor}} |
| } |
| |
| Target t5() { |
| CopyOnly& r = copyonly; |
| return r; |
| } |
| |
| Target t6() { |
| CopyOnly&& r = static_cast<CopyOnly&&>(copyonly); |
| return r; // cxx20_2b-error {{invokes a deleted function}} |
| } |
| |
| Target t7() { |
| MoveOnly& r = moveonly; |
| return r; // expected-error {{no viable conversion}} |
| } |
| |
| Target t8() { |
| MoveOnly&& r = static_cast<MoveOnly&&>(moveonly); |
| return r; // cxx11_17-error {{no viable conversion}} |
| } |
| |
| } // namespace test_lvalue_ref_is_not_moved_from |
| |
| namespace test_rvalue_ref_to_nonobject { |
| |
| struct CopyOnly {}; |
| struct MoveOnly {}; |
| |
| struct Target { |
| Target(CopyOnly (&)()); |
| Target(CopyOnly (&&)()) = delete; |
| Target(MoveOnly (&)()) = delete; // expected-note {{has been explicitly marked deleted here}} |
| // expected-note@-1 {{has been explicitly marked deleted here}} |
| Target(MoveOnly (&&)()); |
| }; |
| |
| CopyOnly make_copyonly(); |
| MoveOnly make_moveonly(); |
| |
| Target t1() { |
| CopyOnly (&r)() = make_copyonly; |
| return r; |
| } |
| |
| Target t2() { |
| CopyOnly (&&r)() = static_cast<CopyOnly(&&)()>(make_copyonly); |
| return r; // OK in all modes; not subject to implicit move |
| } |
| |
| Target t3() { |
| MoveOnly (&r)() = make_moveonly; |
| return r; // expected-error {{invokes a deleted function}} |
| } |
| |
| Target t4() { |
| MoveOnly (&&r)() = static_cast<MoveOnly(&&)()>(make_moveonly); |
| return r; // expected-error {{invokes a deleted function}} |
| } |
| |
| } // namespace test_rvalue_ref_to_nonobject |
| |
| namespace test_simpler_implicit_move { |
| |
| struct CopyOnly { |
| CopyOnly(); |
| CopyOnly(CopyOnly &); |
| }; |
| struct MoveOnly { |
| MoveOnly(); |
| MoveOnly(MoveOnly &&); |
| }; |
| MoveOnly &&rref(); |
| |
| MoveOnly &&test1(MoveOnly &&w) { |
| return w; // expected-error {{cannot bind to lvalue of type}} |
| } |
| |
| CopyOnly test2(bool b) { |
| static CopyOnly w1; |
| CopyOnly w2; |
| if (b) { |
| return w1; |
| } else { |
| return w2; |
| } |
| } |
| |
| template <class T> T &&test3(T &&x) { return x; } // expected-error {{cannot bind to lvalue of type}} |
| template MoveOnly& test3<MoveOnly&>(MoveOnly&); |
| template MoveOnly&& test3<MoveOnly>(MoveOnly&&); // expected-note {{in instantiation of function template specialization}} |
| |
| MoveOnly &&test4() { |
| MoveOnly &&x = rref(); |
| return x; // expected-error {{cannot bind to lvalue of type}} |
| } |
| |
| void test5() try { |
| CopyOnly x; |
| throw x; |
| } catch (...) { |
| } |
| |
| } // namespace test_simpler_implicit_move |