Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / SemaCXX / cxx2b-deducing-this.cpp
blob0033541fa322dc4f9e0089f2b5577931c3700373
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}}
15 struct S {
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}}
35 namespace Override {
36 struct A {
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}}
42 // CWG2553
43 struct B : A {
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 {
63 int fun();
64 int m;
65 void f(this auto) {
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 {
73 void foo();
74 int n;
75 static int i;
78 struct CannotUseThisDerived : CannotUseThisBase {
79 void bar(this auto) {
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}}
82 i = 100;
86 namespace ThisInLambdaWithCaptures {
88 struct Test {
89 Test(auto&&);
92 void test() {
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}}
97 struct Derived;
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){};
103 Derived dok{ok};
104 dok();
106 struct DerivedErr : decltype(ko){};
107 DerivedErr dko{ko};
108 dko();
110 auto alsoOk = [](this const Test &) {};
111 alsoOk();
114 struct Frobble;
115 auto nothingIsOkay = [i = 0](this const Frobble &) {}; // expected-note {{candidate function not viable: requires 0 non-object arguments, but 1 was provided}}
116 struct Frobble {} f;
117 void test2() {
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);
142 void d(this 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);
156 void a(long);
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);
171 void d(this int);
173 void e(this const CorrespondingTpl&&); // expected-note {{here}}
174 void e() const &&; // expected-error{{cannot be redeclared}}
177 struct C {
178 template <typename T>
179 C(T){}
182 void func(int i) {
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) {};
190 D d{l};
191 d();
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 {
202 void a();
203 void b() {
204 a(); // ok, (*this).a()
207 void f(this const Over_Call_Func_Example&); // expected-note {{here}}
208 void g() const {
209 f(); // ok: (*this).f()
210 f(*this); // expected-error{{too many non-object arguments to function call}}
211 this->f(); // ok
214 static void h() {
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
220 void k(this int);
221 operator int() const;
222 void m(this const Over_Call_Func_Example& c) {
223 c.k(); // ok
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}}
239 struct IntToShort {
240 void s(this short);
241 operator int() const;
242 void test(this const IntToShort &val) {
243 val.s();
247 struct ShortToInt {
248 void s(this int);
249 operator short() const;
250 void test(this const ShortToInt &val) {
251 val.s();
255 namespace arity_diagnostics {
256 struct S {
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}}
263 int test() {
264 void(*f)(S&&, int, int) = &S::f;
265 f(S{}, 1, 2);
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}}
270 S{}.f(1, 2);
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 {
282 struct s {
283 static void f(int);
284 void f(this auto &&) {}
285 void g(this s &&) {};
287 void test_qual() {
288 using F = void(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}}
291 F* c = &s::f;
292 F* d = &s::g;
296 void test() {
297 using F = void(s&&);
298 F* a = &s::f;
299 F* b = &s::g;
300 a(s{});
301 b(s{});
306 namespace std {
307 struct strong_ordering {
308 int n;
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>
326 struct Wrap {
327 void f();
328 struct S {
329 operator int(this auto&& self) {
330 static_assert(is_same<decltype(self), typename T<S>::type>);
331 return 0;
333 Wrap* operator->(this auto&& self) {
334 static_assert(is_same<decltype(self), typename T<S>::type>);
335 return new Wrap();
337 int operator[](this auto&& self, int) {
338 static_assert(is_same<decltype(self), typename T<S>::type>);
339 return 0;
341 int operator()(this auto&& self, int) {
342 static_assert(is_same<decltype(self), typename T<S>::type>);
343 return 0;
345 int operator++(this auto&& self, int) {
346 static_assert(is_same<decltype(self), typename T<S>::type>);
347 return 0;
349 int operator++(this auto&& self) {
350 static_assert(is_same<decltype(self), typename T<S>::type>);
351 return 0;
353 int operator--(this auto&& self, int) {
354 static_assert(is_same<decltype(self), typename T<S>::type>);
355 return 0;
357 int operator--(this auto&& self) {
358 static_assert(is_same<decltype(self), typename T<S>::type>);
359 return 0;
361 int operator*(this auto&& self) {
362 static_assert(is_same<decltype(self), typename T<S>::type>);
363 return 0;
365 bool operator==(this auto&& self, int) {
366 static_assert(is_same<decltype(self), typename T<S>::type>);
367 return false;
369 bool operator<=>(this auto&& self, int) {
370 static_assert(is_same<decltype(self), typename T<S>::type>);
371 return false;
373 bool operator<<(this auto&& self, int b) {
374 static_assert(is_same<decltype(self), typename T<S>::type>);
375 return false;
380 template <typename T>
381 struct lvalue_reference {
382 using type = T&;
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 {
394 using type = T&&;
396 template <typename T>
397 struct const_rvalue_reference {
398 using type = const T&&;
402 void test() {
404 Wrap<lvalue_reference>::S s;
405 s++;
406 s.operator++(0);
407 ++s;
408 s.operator++();
409 s--;
410 s.operator--(0);
411 --s;
412 s.operator--();
413 s[0];
414 s.operator[](0);
415 s(0);
416 s.operator()(0);
418 s.operator*();
419 s->f();
420 s.operator->();
421 int i = s;
422 (void)(s << 0);
423 s.operator<<(0);
424 (void)(s == 0);
425 s.operator==(0);
426 (void)(s <=> 0);
427 s.operator<=>(0);
430 const Wrap<const_lvalue_reference>::S s;
431 s++;
432 s.operator++(0);
433 ++s;
434 s.operator++();
435 s--;
436 s.operator--(0);
437 --s;
438 s.operator--();
439 s[0];
440 s.operator[](0);
441 s(0);
442 s.operator()(0);
444 s.operator*();
445 s->f();
446 s.operator->();
447 int i = s;
448 (void)(s << 0);
449 s.operator<<(0);
450 (void)(s == 0);
451 s.operator==(0);
452 (void)(s <=> 0);
453 s.operator<=>(0);
456 volatile Wrap<volatile_lvalue_reference>::S s;
457 s++;
458 s.operator++(0);
459 ++s;
460 s.operator++();
461 s--;
462 s.operator--(0);
463 --s;
464 s.operator--();
465 s[0];
466 s.operator[](0);
467 s(0);
468 s.operator()(0);
470 s.operator*();
471 s->f();
472 s.operator->();
473 int i = s;
474 (void)(s << 0);
475 s.operator<<(0);
476 (void)(s == 0);
477 s.operator==(0);
478 (void)(s <=> 0);
479 s.operator<=>(0);
482 Wrap<rvalue_reference>::S s;
483 using M = Wrap<rvalue_reference>::S&&;
484 ((M)s)++;
485 ((M)s).operator++(0);
486 ++((M)s);
487 ((M)s).operator++();
488 ((M)s)--;
489 ((M)s).operator--(0);
490 --((M)s);
491 ((M)s).operator--();
492 ((M)s)[0];
493 ((M)s).operator[](0);
494 ((M)s)(0);
495 ((M)s).operator()(0);
496 *((M)s);
497 ((M)s).operator*();
498 ((M)s)->f();
499 ((M)s).operator->();
500 int i = ((M)s);
501 (void)(((M)s) << 0);
502 ((M)s).operator<<(0);
503 (void)(((M)s) == 0);
504 ((M)s).operator==(0);
505 (void)(((M)s) <=> 0);
506 ((M)s).operator<=>(0);
511 namespace conversions {
512 //[over.best.ics]
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&&); };
519 B b;
520 X x{{b}}; // expected-error{{no matching constructor for initialization of 'X'}}
522 struct T{}; // expected-note 2{{candidate constructor}}
523 struct C {
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}}
528 void foo(C c) {
529 T d = c; // expected-error {{no viable conversion from 'C' to 'T'}}
534 namespace surrogate {
535 using fn_t = void();
536 struct C {
537 operator fn_t * (this C const &);
540 void foo(C c) {
541 c();
547 namespace GH69838 {
548 struct S {
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}}
562 int test() {
563 S s;
564 s.f();
565 s.g();
566 s.h();
567 s.i(0);
568 s.j({});
569 nonmember(S{});
574 namespace GH69962 {
575 struct S {
576 S(const S&);
579 struct Thing {
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 {
585 S name_;
589 namespace GH69233 {
590 struct Base {};
591 struct S : Base {
592 int j;
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}}
599 struct S2 {
600 S2& operator=(this int&& self, const S2&);
601 S2& operator=(this int&& self, S2&&);
602 operator int();
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'}}
611 struct Move {
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}}
618 void test() {
619 S s;
620 s = s; // expected-error {{object of type 'S' cannot be assigned because its copy assignment operator is implicitly deleted}}
621 S2 s2;
622 s2 = s2;
624 Move m;
625 m = Move{}; // expected-error {{object of type 'Move' cannot be assigned because its copy assignment operator is implicitly deleted}}