// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected,cxx11_23,cxx23 %s
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected,cxx98_20,cxx11_23,cxx11_20 %s
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fcxx-exceptions -verify=expected,cxx98_20,cxx11_23,cxx11_20 %s
// RUN: %clang_cc1 -std=c++98 -fsyntax-only -fcxx-exceptions -Wno-c++11-extensions -verify=expected,cxx98_20,cxx98 %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 '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 'C' to '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
// 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;
};
A1 test1(A1 &&a) {
return a;
}
struct A2 {
A2(A2 &&);
private:
A2(const A2 &);
};
A2 test2(A2 &&a) {
return a;
}
struct B1 {
B1(const B1 &);
B1(B1 &&) = delete; // expected-note {{'B1' has been explicitly marked deleted here}}
};
B1 test3(B1 &&b) {
return b; // expected-error {{call to deleted constructor of 'B1'}}
}
struct B2 {
B2(const B2 &);
private:
B2(B2 &&); // expected-note {{declared private here}}
};
B2 test4(B2 &&b) {
return b; // expected-error {{calling a private constructor of class 'test_implicitly_movable_rvalue_ref::B2'}}
}
} // namespace test_implicitly_movable_rvalue_ref
// 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;
// expected-note@-1 2{{'A1' has been explicitly marked deleted here}}
// cxx11_23-note@-2 3{{'A1' has been explicitly marked deleted here}}
};
void test1() {
try {
func();
} catch (A1 a) {
throw a; // expected-error {{call to deleted constructor of 'A1'}}
}
}
struct A2 {
A2(const A2 &);
private:
A2(A2 &&); // expected-note {{declared private here}}
};
void test2() {
try {
func();
} catch (A2 a) {
throw a; // expected-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 'A1'}}
}
#if __cplusplus >= 201103L
namespace PR54341 {
void test4(A1 a) {
void f(decltype((throw a, 0)));
// expected-error@-1 {{call to deleted constructor of 'A1'}}
void g(int = decltype(throw a, 0){});
// expected-error@-1 {{call to deleted constructor of 'A1'}}
}
void test5(A1 a, int = decltype(throw a, 0){}) {}
// expected-error@-1 {{call to deleted constructor of 'A1'}}
} // namespace PR54341
#endif
} // namespace test_throw_parameter
// 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;
};
C test1() {
A1 a;
return a;
}
struct A2 {
operator C() &&;
private:
operator C() const &;
};
C test2() {
A2 a;
return a;
}
struct B1 {
operator C() const &;
operator C() && = delete; // expected-note {{'operator C' has been explicitly marked deleted here}}
};
C test3() {
B1 b;
return b; // expected-error {{conversion function from 'B1' to 'C' invokes a deleted function}}
}
struct B2 {
operator C() const &;
private:
operator C() &&; // expected-note {{declared private here}}
};
C test4() {
B2 b;
return b; // expected-error {{'operator C' is a private member of 'test_non_ctor_conversion::B2'}}
}
} // namespace test_non_ctor_conversion
// 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); // cxx98-note 2 {{passing argument to parameter here}}
NeedValue(A2);
NeedValue(B1); // cxx11_23-note 2 {{passing argument to parameter here}}
NeedValue(B2);
};
struct A1 {
A1();
A1(A1 &&);
A1(const A1 &) = delete; // cxx98-note 2 {{marked deleted here}}
};
NeedValue test_1_1() {
// not rvalue reference
// same type
A1 a;
return a; // cxx98-error {{call to deleted constructor}}
}
class DerivedA1 : public A1 {};
A1 test_1_2() {
// rvalue reference
// not same type
DerivedA1 a;
return a;
}
NeedValue test_1_3() {
// not rvalue reference
// not same type
DerivedA1 a;
return a; // cxx98-error {{call to deleted constructor}}
}
struct A2 {
A2();
A2(A2 &&);
private:
A2(const A2 &); // cxx98-note 2 {{declared private here}}
};
NeedValue test_2_1() {
// not rvalue reference
// same type
A2 a;
return a; // cxx98-error {{calling a private constructor}}
}
class DerivedA2 : public A2 {};
A2 test_2_2() {
// rvalue reference
// not same type
DerivedA2 a;
return a;
}
NeedValue test_2_3() {
// not rvalue reference
// not same type
DerivedA2 a;
return a; // cxx98-error {{calling a private constructor}}
}
struct B1 {
B1();
B1(const B1 &);
B1(B1 &&) = delete; // cxx11_23-note 3 {{'B1' has been explicitly marked deleted here}}
// cxx98-note@-1 {{'B1' has been explicitly marked deleted here}}
};
NeedValue test_3_1() {
// not rvalue reference
// same type
B1 b;
return b; // cxx11_23-error {{call to deleted constructor of 'B1'}}
}
class DerivedB1 : public B1 {};
B1 test_3_2() {
// rvalue reference
// not same type
DerivedB1 b;
return b; // expected-error {{call to deleted constructor of 'B1'}}
}
NeedValue test_3_3() {
// not rvalue reference
// not same type
DerivedB1 b;
return b; // cxx11_23-error {{call to deleted constructor of 'B1'}}
}
struct B2 {
B2();
B2(const B2 &);
private:
B2(B2 &&); // cxx11_23-note 3 {{declared private here}}
// cxx98-note@-1 {{declared private here}}
};
NeedValue test_4_1() {
// not rvalue reference
// same type
B2 b;
return b; // cxx11_23-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; // expected-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; // cxx11_23-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}}
// cxx11_23-note@-2 {{candidate constructor (the implicit move constructor) not viable}}
struct CopyOnly {
CopyOnly(CopyOnly &&) = delete; // expected-note {{has been explicitly marked deleted here}}
CopyOnly(CopyOnly&);
operator Target() && = delete; // expected-note {{has been explicitly marked deleted here}}
operator Target() &;
};
struct MoveOnly {
MoveOnly(MoveOnly &&); // cxx11_23-note {{copy constructor is implicitly deleted because}}
operator Target() &&; // expected-note {{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; // expected-error {{call to deleted constructor}}
}
MoveOnly t3() {
MoveOnly& r = moveonly;
return r; // cxx11_23-error {{call to implicitly-deleted copy constructor}}
}
MoveOnly t4() {
MoveOnly&& r = static_cast<MoveOnly&&>(moveonly);
return r;
}
Target t5() {
CopyOnly& r = copyonly;
return r;
}
Target t6() {
CopyOnly&& r = static_cast<CopyOnly&&>(copyonly);
return r; // expected-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;
}
} // 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 2{{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
// Both tests in test_constandnonconstcopy, and also test_conversion::test1, are
// "pure" C++98 tests (pretend 'delete' means 'private').
// However we may extend implicit moves into C++98, we must make sure the
// results in these are not changed.
namespace test_constandnonconstcopy {
struct ConstCopyOnly {
ConstCopyOnly();
ConstCopyOnly(ConstCopyOnly &) = delete; // cxx98-note {{marked deleted here}}
ConstCopyOnly(const ConstCopyOnly &);
};
ConstCopyOnly t1() {
ConstCopyOnly x;
return x; // cxx98-error {{call to deleted constructor}}
}
struct NonConstCopyOnly {
NonConstCopyOnly();
NonConstCopyOnly(NonConstCopyOnly &);
NonConstCopyOnly(const NonConstCopyOnly &) = delete; // cxx11_23-note {{marked deleted here}}
};
NonConstCopyOnly t2() {
NonConstCopyOnly x;
return x; // cxx11_23-error {{call to deleted constructor}}
}
} // namespace test_constandnonconstcopy
namespace test_conversion {
struct B;
struct A {
A(B &) = delete; // cxx98-note {{has been explicitly deleted}}
};
struct B {
operator A(); // cxx98-note {{candidate function}}
};
A test1(B x) { return x; } // cxx98-error-re {{conversion {{.*}} is ambiguous}}
struct C {};
struct D {
operator C() &;
operator C() const & = delete; // expected-note {{marked deleted here}}
};
C test2(D x) { return x; } // expected-error {{invokes a deleted function}}
} // namespace test_conversion
namespace test_simpler_implicit_move {
struct CopyOnly {
CopyOnly(); // cxx23-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
// cxx23-note@-1 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
CopyOnly(CopyOnly &); // cxx23-note {{candidate constructor not viable: expects an lvalue for 1st argument}}
// cxx23-note@-1 {{candidate constructor not viable: expects an lvalue for 1st argument}}
};
struct MoveOnly {
MoveOnly();
MoveOnly(MoveOnly &&);
};
MoveOnly &&rref();
MoveOnly &&test1(MoveOnly &&w) {
return w; // cxx98_20-error {{cannot bind to lvalue of type}}
}
CopyOnly test2(bool b) {
static CopyOnly w1;
CopyOnly w2;
if (b) {
return w1;
} else {
return w2; // cxx23-error {{no matching constructor for initialization}}
}
}
template <class T> T &&test3(T &&x) { return x; } // cxx98_20-error {{cannot bind to lvalue of type}}
template MoveOnly& test3<MoveOnly&>(MoveOnly&);
template MoveOnly &&test3<MoveOnly>(MoveOnly &&); // cxx98_20-note {{in instantiation of function template specialization}}
MoveOnly &&test4() {
MoveOnly &&x = rref();
return x; // cxx98_20-error {{cannot bind to lvalue of type}}
}
void test5() try {
CopyOnly x;
throw x; // cxx23-error {{no matching constructor for initialization}}
} catch (...) {
}
} // namespace test_simpler_implicit_move
namespace test_auto_variables {
struct S {};
template <class T> struct range {
S *begin() const;
S *end() const;
};
template <class T> S test_dependent_ranged_for() {
for (auto x : range<T>())
return x;
return S();
}
template S test_dependent_ranged_for<int>();
template <class T> struct X {};
template <class T> X<T> test_dependent_invalid_decl() {
auto x = X<T>().foo(); // expected-error {{no member named 'foo'}}
return x;
}
template X<int> test_dependent_invalid_decl<int>(); // expected-note {{requested here}}
} // namespace test_auto_variables
namespace PR51708 {
class a1; // expected-note 4 {{forward declaration of 'PR51708::a1'}}
template <class> class A2; // expected-note 4 {{template is declared here}}
using a2 = A2<int>;
template <class b> b f() {
// expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}}
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
b d;
// expected-error@-1 {{variable has incomplete type 'PR51708::a1'}}
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
return d;
}
template a1 f<a1>(); // expected-note-re {{in instantiation {{.*}} requested here}}
template a2 f<a2>(); // expected-note-re {{in instantiation {{.*}} requested here}}
template <class b> b g() {
// expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}}
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
b d __attribute__((aligned(1)));
// expected-error@-1 {{variable has incomplete type 'PR51708::a1'}}
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
return d;
}
template a1 g<a1>(); // expected-note-re {{in instantiation {{.*}} requested here}}
template a2 g<a2>(); // expected-note-re {{in instantiation {{.*}} requested here}}
} // namespace PR51708