1 // RUN: %clang_cc1 -fsyntax-only -std=c++2b -Woverloaded-virtual %s -verify
4 // FIXME: can we improve these diagnostics?
5 void f(this); // expected-error{{variable has incomplete type 'void'}} \
6 // expected-error{{invalid use of 'this' outside of a non-static member function}}
8 void g(this auto); // expected-error{{an explicit object parameter cannot appear in a non-member function}}
10 auto l1
= [] (this auto) static {}; // expected-error{{an explicit object parameter cannot appear in a static lambda}}
11 auto l2
= [] (this auto) mutable {}; // expected-error{{a lambda with an explicit object parameter cannot be mutable}}
12 auto l3
= [](this auto...){}; // expected-error {{the explicit object parameter cannot be a function parameter pack}}
13 auto l4
= [](int, this auto){}; // expected-error {{an explicit object parameter can only appear as the first parameter of the lambda}}
16 static void f(this auto); // expected-error{{an explicit object parameter cannot appear in a static function}}
17 virtual void f(this S
); // expected-error{{an explicit object parameter cannot appear in a virtual function}}
19 void g(this auto) const; // expected-error{{explicit object member function cannot have 'const' qualifier}}
20 void h(this auto) &; // expected-error{{explicit object member function cannot have '&' qualifier}}
21 void i(this auto) &&; // expected-error{{explicit object member function cannot have '&&' qualifier}}
22 void j(this auto) volatile; // expected-error{{explicit object member function cannot have 'volatile' qualifier}}
23 void k(this auto) __restrict
; // expected-error{{explicit object member function cannot have '__restrict' qualifier}}
24 void l(this auto) _Nonnull
; // expected-error{{explicit object member function cannot have '' qualifie}}
27 void variadic(this auto...); // expected-error{{the explicit object parameter cannot be a function parameter pack}}
28 void not_first(int, this auto); // expected-error {{an explicit object parameter can only appear as the first parameter of the function}}
30 S(this auto); // expected-error {{an explicit object parameter cannot appear in a constructor}}
31 ~S(this S
) {} // expected-error {{an explicit object parameter cannot appear in a destructor}} \
32 // expected-error {{destructor cannot have any parameters}}
37 virtual void f(); // expected-note 2{{here}}
38 virtual void g(int); // expected-note {{here}}
39 virtual void h() const; // expected-note 5{{here}}
44 int f(this B
&, int); // expected-warning {{hides overloaded virtual function}}
45 int f(this B
&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
46 int g(this B
&); // expected-warning {{hides overloaded virtual function}}
47 int h(this B
&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
48 int h(this B
&&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
49 int h(this const B
&&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
50 int h(this A
&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
51 int h(this int); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
55 namespace DefaultArgs
{
56 struct Test
{ void f(this const auto& = Test
{}); };
57 // expected-error@-1 {{the explicit object parameter cannot have a default argument}}
58 auto L
= [](this const auto& = Test
{}){};
59 // expected-error@-1 {{the explicit object parameter cannot have a default argument}}
62 struct CannotUseThis
{
66 this->fun(); // expected-error{{invalid use of 'this' in a function with an explicit object parameter}}
67 fun(); // expected-error {{call to non-static member function without an object argument}}
68 m
= 0; // expected-error {{invalid use of member 'm' in explicit object member function}}
72 struct CannotUseThisBase
{
78 struct CannotUseThisDerived
: CannotUseThisBase
{
80 foo(); // expected-error {{call to non-static member function without an object argument}}
81 n
= 12; // expected-error {{invalid use of member 'n' in explicit object member function}}
86 namespace ThisInLambdaWithCaptures
{
94 [i
= 0](this Test
) { }();
95 // expected-error@-1 {{invalid explicit object parameter type 'ThisInLambdaWithCaptures::Test' in lambda with capture; the type must be the same as, or derived from, the lambda}}
98 auto ok
= [i
= 0](this const Derived
&) {};
99 auto ko
= [i
= 0](this const Test
&) {};
100 // expected-error@-1 {{invalid explicit object parameter type 'ThisInLambdaWithCaptures::Test' in lambda with capture; the type must be the same as, or derived from, the lambda}}
102 struct Derived
: decltype(ok
){};
106 struct DerivedErr
: decltype(ko
){};
110 auto alsoOk
= [](this const Test
&) {};
115 auto nothingIsOkay
= [i
= 0](this const Frobble
&) {}; // expected-note {{candidate function not viable: requires 0 non-object arguments, but 1 was provided}}
118 nothingIsOkay(f
); // expected-error {{no matching function for call to object of type}}
123 struct Corresponding
{
124 void a(this Corresponding
&); // expected-note 2{{here}}
125 void a(); // expected-error{{cannot be redeclared}}
126 void a() &; // expected-error{{cannot be redeclared}}
127 void a(this Corresponding
&, int);
128 void a(this Corresponding
&, double);
130 void b(this const Corresponding
&); // expected-note 2{{here}}
131 void b() const; // expected-error{{cannot be redeclared}}
132 void b() const &; // expected-error{{cannot be redeclared}}
134 void c(this Corresponding
&&); // expected-note {{here}}
135 void c() &&; // expected-error{{cannot be redeclared}}
137 void d(this Corresponding
&);
138 void d(this Corresponding
&&);
139 void d(this const Corresponding
&);
140 void d(this const int&);
141 void d(this const int);
144 void e(this const Corresponding
&&); // expected-note {{here}}
145 void e() const &&; // expected-error{{cannot be redeclared}}
149 template <typename T
>
150 struct CorrespondingTpl
{
151 void a(this CorrespondingTpl
&); // expected-note 2{{here}}
152 void a(); // expected-error{{cannot be redeclared}}
153 void a() &; // expected-error{{cannot be redeclared}}
154 void a(this Corresponding
&, int);
155 void a(this Corresponding
&, double);
159 void b(this const CorrespondingTpl
&); // expected-note 2{{here}}
160 void b() const; // expected-error{{cannot be redeclared}}
161 void b() const &; // expected-error{{cannot be redeclared}}
163 void c(this CorrespondingTpl
&&); // expected-note {{here}}
164 void c() &&; // expected-error{{cannot be redeclared}}
166 void d(this Corresponding
&);
167 void d(this Corresponding
&&);
168 void d(this const Corresponding
&);
169 void d(this const int&);
170 void d(this const int);
173 void e(this const CorrespondingTpl
&&); // expected-note {{here}}
174 void e() const &&; // expected-error{{cannot be redeclared}}
178 template <typename T
>
183 (void)[=](this auto&&) { return i
; }();
184 (void)[=](this const auto&) { return i
; }();
185 (void)[i
](this C
) { return i
; }(); // expected-error{{invalid explicit object parameter type 'C'}}
186 (void)[=](this C
) { return i
; }(); // expected-error{{invalid explicit object parameter type 'C'}}
187 (void)[](this C
) { return 42; }();
188 auto l
= [=](this auto&) {};
189 struct D
: decltype(l
) {};
194 void TestMutationInLambda() {
195 [i
= 0](this auto &&){ i
++; }();
196 [i
= 0](this auto){ i
++; }();
197 [i
= 0](this const auto&){ i
++; }();
198 // expected-error@-1 {{cannot assign to a variable captured by copy in a non-mutable lambda}}
201 struct Over_Call_Func_Example
{
204 a(); // ok, (*this).a()
207 void f(this const Over_Call_Func_Example
&); // expected-note {{here}}
209 f(); // ok: (*this).f()
210 f(*this); // expected-error{{too many non-object arguments to function call}}
215 f(); // expected-error{{call to non-static member function without an object argument}}
216 f(Over_Call_Func_Example
{}); // expected-error{{call to non-static member function without an object argument}}
217 Over_Call_Func_Example
{}.f(); // ok
221 operator int() const;
222 void m(this const Over_Call_Func_Example
& c
) {
227 struct AmbiguousConversion
{
228 void f(this int); // expected-note {{candidate function}}
229 void f(this float); // expected-note {{candidate function}}
231 operator int() const;
232 operator float() const;
234 void test(this const AmbiguousConversion
&s
) {
235 s
.f(); // expected-error {{call to member function 'f' is ambiguous}}
241 operator int() const;
242 void test(this const IntToShort
&val
) {
249 operator short() const;
250 void test(this const ShortToInt
&val
) {
255 namespace arity_diagnostics
{
257 void f(this auto &&, auto, auto); // expected-note {{requires 2 non-object arguments, but 0 were provided}}
258 void g(this auto &&, auto, auto); // expected-note {{requires 2 non-object arguments, but 3 were provided}}
259 void h(this auto &&, int, int i
= 0); // expected-note {{requires at least 1 non-object argument, but 0 were provided}}
260 void i(this S
&&, int); // expected-note 2{{declared here}}
264 void(*f
)(S
&&, int, int) = &S::f
;
266 f(S
{}, 1); // expected-error {{too few arguments to function call, expected 3, have 2}}
267 f(S
{}); // expected-error {{too few arguments to function call, expected 3, have 1}}
268 f(S
{}, 1, 2, 3); //expected-error {{too many arguments to function call, expected 3, have 4}}
271 S
{}.f(); // expected-error{{no matching member function for call to 'f'}}
272 S
{}.g(1,2,3); // expected-error {{no matching member function for call to 'g'}}
273 S
{}.h(); // expected-error {{no matching member function for call to 'h'}}
274 S
{}.i(); // expected-error {{too few non-object arguments to function call, expected 1, have 0}}
275 S
{}.i(1, 2, 3); // expected-error {{too many non-object arguments to function call, expected 1, have 3}}
280 namespace AddressOf
{
284 void f(this auto &&) {}
285 void g(this s
&&) {};
289 F
* a
= &f
; // expected-error {{must explicitly qualify name of member function when taking its address}}
290 F
* b
= &g
; // expected-error {{must explicitly qualify name of member function when taking its address}}
307 struct strong_ordering
{
309 constexpr operator int() const { return n
; }
310 static const strong_ordering equal
, greater
, less
;
312 constexpr strong_ordering
strong_ordering::equal
= {0};
313 constexpr strong_ordering
strong_ordering::greater
= {1};
314 constexpr strong_ordering
strong_ordering::less
= {-1};
317 namespace operators_deduction
{
319 template <typename T
, typename U
>
320 constexpr bool is_same
= false;
322 template <typename T
>
323 constexpr bool is_same
<T
, T
> = true;
325 template <template <typename
> typename T
>
329 operator int(this auto&& self
) {
330 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
333 Wrap
* operator->(this auto&& self
) {
334 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
337 int operator[](this auto&& self
, int) {
338 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
341 int operator()(this auto&& self
, int) {
342 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
345 int operator++(this auto&& self
, int) {
346 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
349 int operator++(this auto&& self
) {
350 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
353 int operator--(this auto&& self
, int) {
354 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
357 int operator--(this auto&& self
) {
358 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
361 int operator*(this auto&& self
) {
362 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
365 bool operator==(this auto&& self
, int) {
366 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
369 bool operator<=>(this auto&& self
, int) {
370 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
373 bool operator<<(this auto&& self
, int b
) {
374 static_assert(is_same
<decltype(self
), typename T
<S
>::type
>);
380 template <typename T
>
381 struct lvalue_reference
{
384 template <typename T
>
385 struct const_lvalue_reference
{
386 using type
= const T
&;
388 template <typename T
>
389 struct volatile_lvalue_reference
{
390 using type
= volatile T
&;
392 template <typename T
>
393 struct rvalue_reference
{
396 template <typename T
>
397 struct const_rvalue_reference
{
398 using type
= const T
&&;
404 Wrap
<lvalue_reference
>::S s
;
430 const Wrap
<const_lvalue_reference
>::S s
;
456 volatile Wrap
<volatile_lvalue_reference
>::S s
;
482 Wrap
<rvalue_reference
>::S s
;
483 using M
= Wrap
<rvalue_reference
>::S
&&;
485 ((M
)s
).operator++(0);
489 ((M
)s
).operator--(0);
493 ((M
)s
).operator[](0);
495 ((M
)s
).operator()(0);
502 ((M
)s
).operator<<(0);
504 ((M
)s
).operator==(0);
505 (void)(((M
)s
) <=> 0);
506 ((M
)s
).operator<=>(0);
511 namespace conversions
{
513 struct Y
{ Y(int); }; //expected-note 3{{candidate}}
514 struct A
{ operator int(this auto&&); }; //expected-note {{candidate}}
515 Y y1
= A(); // expected-error{{no viable conversion from 'A' to 'Y'}}
517 struct X
{ X(); }; //expected-note 3{{candidate}}
518 struct B
{ operator X(this auto&&); };
520 X x
{{b
}}; // expected-error{{no matching constructor for initialization of 'X'}}
522 struct T
{}; // expected-note 2{{candidate constructor}}
524 operator T (this int); // expected-note {{candidate function not viable: no known conversion from 'C' to 'int' for object argument}}
525 operator int() const; // expected-note {{candidate function}}
529 T d
= c
; // expected-error {{no viable conversion from 'C' to 'T'}}
534 namespace surrogate
{
537 operator fn_t
* (this C
const &);
549 S(this auto &self
) {} // expected-error {{an explicit object parameter cannot appear in a constructor}}
550 virtual void f(this S self
) {} // expected-error {{an explicit object parameter cannot appear in a virtual function}}
551 void g(this auto &self
) const {} // expected-error {{explicit object member function cannot have 'const' qualifier}}
552 void h(this S self
= S
{}) {} // expected-error {{the explicit object parameter cannot have a default argument}}
553 void i(int i
, this S self
= S
{}) {} // expected-error {{an explicit object parameter can only appear as the first parameter of the function}}
554 ~S(this S
&&self
); // expected-error {{an explicit object parameter cannot appear in a destructor}} \
555 // expected-error {{destructor cannot have any parameters}}
557 static void j(this S s
); // expected-error {{an explicit object parameter cannot appear in a static function}}
560 void nonmember(this S s
); // expected-error {{an explicit object parameter cannot appear in a non-member function}}
580 template<typename Self
, typename
... Args
>
581 Thing(this Self
&& self
, Args
&& ... args
) { } // expected-error {{an explicit object parameter cannot appear in a constructor}}
584 class Server
: public Thing
{
593 S
& operator=(this Base
& self
, const S
&) = default;
594 // expected-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
595 // expected-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
596 // expected-note@-3 {{explicitly defaulted function was implicitly deleted here}}
600 S2
& operator=(this int&& self
, const S2
&);
601 S2
& operator=(this int&& self
, S2
&&);
605 S2
& S2::operator=(this int&& self
, const S2
&) = default;
606 // expected-error@-1 {{the type of the explicit object parameter of an explicitly-defaulted copy assignment operator should match the type of the class 'S2'}}
608 S2
& S2::operator=(this int&& self
, S2
&&) = default;
609 // expected-error@-1 {{the type of the explicit object parameter of an explicitly-defaulted move assignment operator should match the type of the class 'S2'}}
612 Move
& operator=(this int&, Move
&&) = default;
613 // expected-warning@-1 {{explicitly defaulted move assignment operator is implicitly deleted}}
614 // expected-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit move assignment operator}}
615 // expected-note@-3 {{copy assignment operator is implicitly deleted because 'Move' has a user-declared move assignment operator}}
620 s
= s
; // expected-error {{object of type 'S' cannot be assigned because its copy assignment operator is implicitly deleted}}
625 m
= Move
{}; // expected-error {{object of type 'Move' cannot be assigned because its copy assignment operator is implicitly deleted}}