xref: /llvm-project/clang/test/SemaCXX/cxx2b-deducing-this.cpp (revision db93ef14aef9c572e02bc842762bc4d0278148f9)
1 // RUN: %clang_cc1 -fsyntax-only -std=c++2b -Woverloaded-virtual %s -verify
2 
3 
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}}
7 
8 void g(this auto); // expected-error{{an explicit object parameter cannot appear in a non-member function}}
9 
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}}
14 
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}}
18 
19     // new and delete are implicitly static
20     void *operator new(this unsigned long); // expected-error{{an explicit object parameter cannot appear in a static function}}
21     void operator delete(this void*); // expected-error{{an explicit object parameter cannot appear in a static function}}
22 
23     void g(this auto) const; // expected-error{{explicit object member function cannot have 'const' qualifier}}
24     void h(this auto) &; // expected-error{{explicit object member function cannot have '&' qualifier}}
25     void i(this auto) &&; // expected-error{{explicit object member function cannot have '&&' qualifier}}
26     void j(this auto) volatile; // expected-error{{explicit object member function cannot have 'volatile' qualifier}}
27     void k(this auto) __restrict; // expected-error{{explicit object member function cannot have '__restrict' qualifier}}
28     void l(this auto) _Nonnull; // expected-error{{explicit object member function cannot have '' qualifie}}
29 
30 
31     void variadic(this auto...); // expected-error{{the explicit object parameter cannot be a function parameter pack}}
32     void not_first(int, this auto); // expected-error {{an explicit object parameter can only appear as the first parameter of the function}}
33 
34     S(this auto); // expected-error {{an explicit object parameter cannot appear in a constructor}}
35     ~S(this S) {} // expected-error {{an explicit object parameter cannot appear in a destructor}} \
36                   // expected-error {{destructor cannot have any parameters}}
37 };
38 
39 namespace Override {
40 struct A {
41     virtual void f(); // expected-note 2{{here}}
42     virtual void g(int); // expected-note {{here}}
43     virtual void h() const; // expected-note 5{{here}}
44 };
45 
46 // CWG2553
47 struct B : A {
48     int f(this B&, int); // expected-warning {{hides overloaded virtual function}}
49     int f(this B&);  // expected-error {{an explicit object parameter cannot appear in a virtual function}}
50     int g(this B&); // expected-warning {{hides overloaded virtual function}}
51     int h(this B&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
52     int h(this B&&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
53     int h(this const B&&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
54     int h(this A&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
55     int h(this int); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
56 };
57 }
58 
59 namespace DefaultArgs {
60      struct Test { void f(this const auto& = Test{}); };
61     // expected-error@-1 {{the explicit object parameter cannot have a default argument}}
62     auto L = [](this const auto& = Test{}){};
63     // expected-error@-1 {{the explicit object parameter cannot have a default argument}}
64 }
65 
66 struct CannotUseThis {
67     int fun();
68     int m;
69     void f(this auto) {
70         this->fun(); // expected-error{{invalid use of 'this' in a function with an explicit object parameter}}
71         fun(); // expected-error {{call to non-static member function without an object argument}}
72         m = 0; // expected-error {{invalid use of member 'm' in explicit object member function}}
73     }
74 };
75 
76 struct CannotUseThisBase {
77   void foo();
78   int n;
79   static int i;
80 };
81 
82 struct CannotUseThisDerived : CannotUseThisBase {
83   void bar(this auto) {
84     foo(); // expected-error {{call to non-static member function without an object argument}}
85     n = 12; // expected-error {{invalid use of member 'n' in explicit object member function}}
86     i = 100;
87   }
88 };
89 
90 namespace ThisInLambdaWithCaptures {
91 
92 struct Test {
93     Test(auto&&);
94 };
95 
96 void test() {
97 
98     [i = 0](this Test) { }();
99     // 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}}
100 
101     struct Derived;
102     auto ok = [i = 0](this const Derived&) {};
103     auto ko = [i = 0](this const Test&) {};
104     // 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}}
105 
106     struct Derived : decltype(ok){};
107     Derived dok{ok};
108     dok();
109 
110     struct DerivedErr : decltype(ko){};
111     DerivedErr dko{ko};
112     dko();
113 
114     auto alsoOk = [](this const Test &) {};
115     alsoOk();
116 }
117 
118 struct Frobble;
119 auto nothingIsOkay = [i = 0](this const Frobble &) {};  // expected-note {{candidate function not viable: requires 0 non-object arguments, but 1 was provided}}
120 struct Frobble {} f;
121 void test2()  {
122     nothingIsOkay(f); // expected-error {{no matching function for call to object of type}}
123 }
124 
125 }
126 
127 struct Corresponding {
128     void a(this Corresponding&); // expected-note 2{{here}}
129     void a(); // expected-error{{cannot be redeclared}}
130     void a() &; // expected-error{{cannot be redeclared}}
131     void a(this Corresponding&, int);
132     void a(this Corresponding&, double);
133 
134     void b(this const Corresponding&); // expected-note 2{{here}}
135     void b() const; // expected-error{{cannot be redeclared}}
136     void b() const &; // expected-error{{cannot be redeclared}}
137 
138     void c(this Corresponding&&); // expected-note {{here}}
139     void c() &&; // expected-error{{cannot be redeclared}}
140 
141     void d(this Corresponding&);
142     void d(this Corresponding&&);
143     void d(this const Corresponding&);
144     void d(this const int&);
145     void d(this const int);  // expected-note {{previous declaration is here}}
146     void d(this int);        // expected-error {{class member cannot be redeclared}}
147 
148     void e(this const Corresponding&&); // expected-note {{here}}
149     void e() const &&; // expected-error{{cannot be redeclared}}
150 
151 };
152 
153 template <typename T>
154 struct CorrespondingTpl {
155     void a(this CorrespondingTpl&); // expected-note 2{{here}}
156     void a(); // expected-error{{cannot be redeclared}}
157     void a() &; // expected-error{{cannot be redeclared}}
158     void a(this Corresponding&, int);
159     void a(this Corresponding&, double);
160     void a(long);
161 
162 
163     void b(this const CorrespondingTpl&); // expected-note 2{{here}}
164     void b() const; // expected-error{{cannot be redeclared}}
165     void b() const &; // expected-error{{cannot be redeclared}}
166 
167     void c(this CorrespondingTpl&&); // expected-note {{here}}
168     void c() &&; // expected-error{{cannot be redeclared}}
169 
170     void d(this Corresponding&);
171     void d(this Corresponding&&);
172     void d(this const Corresponding&);
173     void d(this const int&);
174     void d(this const int); // expected-note {{previous declaration is here}}
175     void d(this int);       // expected-error {{class member cannot be redeclared}}
176     void e(this const CorrespondingTpl&&); // expected-note {{here}}
177     void e() const &&; // expected-error{{cannot be redeclared}}
178 };
179 
180 struct C {
181     template <typename T>
182     C(T){}
183 };
184 
185 void func(int i) {
186     (void)[=](this auto&&) { return i; }();
187     (void)[=](this const auto&) { return i; }();
188     (void)[i](this C) { return i; }(); // expected-error{{invalid explicit object parameter type 'C'}}
189     (void)[=](this C) { return i; }(); // expected-error{{invalid explicit object parameter type 'C'}}
190     (void)[](this C) { return 42; }();
191     auto l = [=](this auto&) {};
192     struct D : decltype(l) {};
193     D d{l};
194     d();
195 }
196 
197 void TestMutationInLambda() {
198     [i = 0](this auto &&){ i++; }();
199     [i = 0](this auto){ i++; }();
200     [i = 0](this const auto&){ i++; }(); // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
201 
202     int x;
203     const auto l1 = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
204     const auto l2 = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
205 
206     const auto l3 = [&x](this auto&) {
207         const auto l3a = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
208         l3a(); // expected-note {{in instantiation of}}
209     };
210 
211     const auto l4 = [&x](this auto&) {
212         const auto l4a = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
213         l4a(); // expected-note {{in instantiation of}}
214     };
215 
216     const auto l5 = [x](this auto&) {
217         const auto l5a = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
218         l5a(); // expected-note {{in instantiation of}}
219     };
220 
221     const auto l6 = [=](this auto&) {
222         const auto l6a = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
223         l6a(); // expected-note {{in instantiation of}}
224     };
225 
226     const auto l7 = [x](this auto&) {
227         const auto l7a = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
228         l7a(); // expected-note {{in instantiation of}}
229     };
230 
231     const auto l8 = [=](this auto&) {
232         const auto l8a = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
233         l8a(); // expected-note {{in instantiation of}}
234     };
235 
236     const auto l9 = [&](this auto&) {
237         const auto l9a = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
238         l9a(); // expected-note {{in instantiation of}}
239     };
240 
241     const auto l10 = [&](this auto&) {
242         const auto l10a = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
243         l10a(); // expected-note {{in instantiation of}}
244     };
245 
246     const auto l11 = [x](this auto&) {
247         const auto l11a = [&x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}} expected-note {{while substituting}}
248         l11a();
249     };
250 
251     const auto l12 = [x](this auto&) {
252         const auto l12a = [&](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}} expected-note {{while substituting}}
253         l12a();
254     };
255 
256     const auto l13 = [=](this auto&) {
257         const auto l13a = [&x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}} expected-note {{while substituting}}
258         l13a();
259     };
260 
261     struct S {
262         int x;
263         auto f() {
264             return [*this] (this auto&&) {
265                 x = 42; // expected-error {{read-only variable is not assignable}}
266                 [*this] () mutable { x = 42; } ();
267                 [*this] (this auto&&) { x = 42; } ();
268                 [*this] () { x = 42; } (); // expected-error {{read-only variable is not assignable}}
269                 const auto l = [*this] (this auto&&) { x = 42; }; // expected-error {{read-only variable is not assignable}}
270                 l(); // expected-note {{in instantiation of}}
271 
272                 struct T {
273                     int x;
274                     auto g() {
275                         return [&] (this auto&&) {
276                             x = 42;
277                             const auto l = [*this] (this auto&&) { x = 42; }; // expected-error {{read-only variable is not assignable}}
278                             l(); // expected-note {{in instantiation of}}
279                         };
280                     }
281                 };
282 
283                 const auto l2 = T{}.g();
284                 l2(); // expected-note {{in instantiation of}}
285             };
286         }
287     };
288 
289     const auto l14 = S{}.f();
290 
291     l1(); // expected-note {{in instantiation of}}
292     l2(); // expected-note {{in instantiation of}}
293     l3(); // expected-note {{in instantiation of}}
294     l4(); // expected-note {{in instantiation of}}
295     l5(); // expected-note {{in instantiation of}}
296     l6(); // expected-note {{in instantiation of}}
297     l7(); // expected-note {{in instantiation of}}
298     l8(); // expected-note {{in instantiation of}}
299     l9(); // expected-note {{in instantiation of}}
300     l10(); // expected-note {{in instantiation of}}
301     l11(); // expected-note {{in instantiation of}}
302     l12(); // expected-note {{in instantiation of}}
303     l13(); // expected-note {{in instantiation of}}
304     l14(); // expected-note 3 {{in instantiation of}}
305 
306     {
307       const auto l1 = [&x](this auto&) { x = 42; };
308       const auto l2 = [&](this auto&) { x = 42; };
309       l1();
310       l2();
311     }
312 
313     // Check that we don't crash if the lambda has type sugar.
314     const auto l15 = [=](this auto&&) [[clang::annotate_type("foo")]] [[clang::annotate_type("bar")]] {
315         return x;
316     };
317 
318     const auto l16 = [=]() [[clang::annotate_type("foo")]] [[clang::annotate_type("bar")]] {
319         return x;
320     };
321 
322     l15();
323     l16();
324 }
325 
326 struct Over_Call_Func_Example {
327     void a();
328     void b() {
329         a(); // ok, (*this).a()
330     }
331 
332     void f(this const Over_Call_Func_Example&); // expected-note {{here}}
333     void g() const {
334         f();       // ok: (*this).f()
335         f(*this);  // expected-error{{too many non-object arguments to function call}}
336         this->f(); // ok
337     }
338 
339     static void h() {
340         f();       // expected-error{{call to non-static member function without an object argument}}
341         f(Over_Call_Func_Example{});   // expected-error{{call to non-static member function without an object argument}}
342         Over_Call_Func_Example{}.f();   // ok
343     }
344 
345     void k(this int);
346     operator int() const;
347     void m(this const Over_Call_Func_Example& c) {
348         c.k();     // ok
349     }
350 };
351 
352 struct AmbiguousConversion {
353   void f(this int); // expected-note {{candidate function}}
354   void f(this float); // expected-note {{candidate function}}
355 
356   operator int() const;
357   operator float() const;
358 
359   void test(this const AmbiguousConversion &s) {
360     s.f(); // expected-error {{call to member function 'f' is ambiguous}}
361   }
362 };
363 
364 struct IntToShort {
365   void s(this short);
366   operator int() const;
367   void test(this const IntToShort &val) {
368     val.s();
369   }
370 };
371 
372 struct ShortToInt {
373   void s(this int);
374   operator short() const;
375   void test(this const ShortToInt &val) {
376     val.s();
377   }
378 };
379 
380 namespace arity_diagnostics {
381 struct S {
382     void f(this auto &&, auto, auto); // expected-note {{requires 2 non-object arguments, but 0 were provided}}
383     void g(this auto &&, auto, auto); // expected-note {{requires 2 non-object arguments, but 3 were provided}}
384     void h(this auto &&, int, int i = 0); // expected-note {{requires at least 1 non-object argument, but 0 were provided}}
385     void i(this S&&, int); // expected-note 2{{declared here}}
386 };
387 
388 int test() {
389     void(*f)(S&&, int, int) = &S::f;
390     f(S{}, 1, 2);
391     f(S{}, 1); // expected-error {{too few arguments to function call, expected 3, have 2}}
392     f(S{}); // expected-error {{too few arguments to function call, expected 3, have 1}}
393     f(S{}, 1, 2, 3); //expected-error {{too many arguments to function call, expected 3, have 4}}
394 
395     S{}.f(1, 2);
396     S{}.f(); //  expected-error{{no matching member function for call to 'f'}}
397     S{}.g(1,2,3); // expected-error {{no matching member function for call to 'g'}}
398     S{}.h(); // expected-error {{no matching member function for call to 'h'}}
399     S{}.i(); // expected-error {{too few non-object arguments to function call, expected 1, have 0}}
400     S{}.i(1, 2, 3); // expected-error {{too many non-object arguments to function call, expected 1, have 3}}
401 }
402 
403 }
404 
405 namespace AddressOf {
406 
407 struct s {
408     static void f(int);
409     void f(this auto &&) {}
410     void g(this s &&) {};
411 
412     void test_qual() {
413         using F = void(s&&);
414         F* a = &f; // expected-error {{must explicitly qualify name of member function when taking its address}}
415         F* b = &g; // expected-error {{must explicitly qualify name of member function when taking its address}}
416         F* c = &s::f;
417         F* d = &s::g;
418     }
419 };
420 
421 void test() {
422     using F = void(s&&);
423     F* a = &s::f;
424     F* b = &s::g;
425     a(s{});
426     b(s{});
427 }
428 
429 }
430 
431 namespace std {
432   struct strong_ordering {
433     int n;
434     constexpr operator int() const { return n; }
435     static const strong_ordering equal, greater, less;
436   };
437   constexpr strong_ordering strong_ordering::equal = {0};
438   constexpr strong_ordering strong_ordering::greater = {1};
439   constexpr strong_ordering strong_ordering::less = {-1};
440 
441   template<typename T> constexpr __remove_reference_t(T)&& move(T&& t) noexcept {
442     return static_cast<__remove_reference_t(T)&&>(t);
443   }
444 }
445 
446 namespace operators_deduction {
447 
448 template <typename T, typename U>
449 constexpr bool is_same = false;
450 
451 template <typename T>
452 constexpr bool is_same<T, T> = true;
453 
454 template <template <typename> typename T>
455 struct Wrap {
456 void f();
457 struct S {
458     operator int(this auto&& self) {
459         static_assert(is_same<decltype(self), typename T<S>::type>);
460         return 0;
461     }
462     Wrap* operator->(this auto&& self) {
463         static_assert(is_same<decltype(self), typename T<S>::type>);
464         return new Wrap();
465     }
466     int operator[](this auto&& self, int) {
467         static_assert(is_same<decltype(self), typename T<S>::type>);
468         return 0;
469     }
470     int operator()(this auto&& self, int) {
471         static_assert(is_same<decltype(self), typename T<S>::type>);
472         return 0;
473     }
474     int operator++(this auto&& self, int) {
475         static_assert(is_same<decltype(self), typename T<S>::type>);
476         return 0;
477     }
478     int operator++(this auto&& self) {
479         static_assert(is_same<decltype(self), typename T<S>::type>);
480         return 0;
481     }
482     int operator--(this auto&& self, int) {
483         static_assert(is_same<decltype(self), typename T<S>::type>);
484         return 0;
485     }
486     int operator--(this auto&& self) {
487         static_assert(is_same<decltype(self), typename T<S>::type>);
488         return 0;
489     }
490     int operator*(this auto&& self) {
491         static_assert(is_same<decltype(self), typename T<S>::type>);
492         return 0;
493     }
494     bool operator==(this auto&& self, int) {
495         static_assert(is_same<decltype(self), typename T<S>::type>);
496         return false;
497     }
498     bool operator<=>(this auto&& self, int) {
499         static_assert(is_same<decltype(self), typename T<S>::type>);
500         return false;
501     }
502     bool operator<<(this auto&& self, int b) {
503         static_assert(is_same<decltype(self), typename T<S>::type>);
504         return false;
505     }
506 };
507 };
508 
509 template <typename T>
510 struct lvalue_reference {
511     using type = T&;
512 };
513 template <typename T>
514 struct const_lvalue_reference {
515     using type = const T&;
516 };
517 template <typename T>
518 struct volatile_lvalue_reference {
519     using type = volatile T&;
520 };
521 template <typename T>
522 struct rvalue_reference {
523     using type = T&&;
524 };
525 template <typename T>
526 struct const_rvalue_reference {
527     using type = const T&&;
528 };
529 
530 
531 void test() {
532     {
533         Wrap<lvalue_reference>::S s;
534         s++;
535         s.operator++(0);
536         ++s;
537         s.operator++();
538         s--;
539         s.operator--(0);
540         --s;
541         s.operator--();
542         s[0];
543         s.operator[](0);
544         s(0);
545         s.operator()(0);
546         *s;
547         s.operator*();
548         s->f();
549         s.operator->();
550         int i = s;
551         (void)(s << 0);
552         s.operator<<(0);
553         (void)(s == 0);
554         s.operator==(0);
555         (void)(s <=> 0);
556         s.operator<=>(0);
557     }
558     {
559         const Wrap<const_lvalue_reference>::S s;
560         s++;
561         s.operator++(0);
562         ++s;
563         s.operator++();
564         s--;
565         s.operator--(0);
566         --s;
567         s.operator--();
568         s[0];
569         s.operator[](0);
570         s(0);
571         s.operator()(0);
572         *s;
573         s.operator*();
574         s->f();
575         s.operator->();
576         int i = s;
577         (void)(s << 0);
578         s.operator<<(0);
579         (void)(s == 0);
580         s.operator==(0);
581         (void)(s <=> 0);
582         s.operator<=>(0);
583     }
584     {
585         volatile Wrap<volatile_lvalue_reference>::S s;
586         s++;
587         s.operator++(0);
588         ++s;
589         s.operator++();
590         s--;
591         s.operator--(0);
592         --s;
593         s.operator--();
594         s[0];
595         s.operator[](0);
596         s(0);
597         s.operator()(0);
598         *s;
599         s.operator*();
600         s->f();
601         s.operator->();
602         int i = s;
603         (void)(s << 0);
604         s.operator<<(0);
605         (void)(s == 0);
606         s.operator==(0);
607         (void)(s <=> 0);
608         s.operator<=>(0);
609     }
610     {
611         Wrap<rvalue_reference>::S s;
612         using M = Wrap<rvalue_reference>::S&&;
613         ((M)s)++;
614         ((M)s).operator++(0);
615         ++((M)s);
616         ((M)s).operator++();
617         ((M)s)--;
618         ((M)s).operator--(0);
619         --((M)s);
620         ((M)s).operator--();
621         ((M)s)[0];
622         ((M)s).operator[](0);
623         ((M)s)(0);
624         ((M)s).operator()(0);
625         *((M)s);
626         ((M)s).operator*();
627         ((M)s)->f();
628         ((M)s).operator->();
629         int i = ((M)s);
630         (void)(((M)s) << 0);
631         ((M)s).operator<<(0);
632         (void)(((M)s) == 0);
633         ((M)s).operator==(0);
634         (void)(((M)s) <=> 0);
635         ((M)s).operator<=>(0);
636     }
637 }
638 }
639 
640 namespace conversions {
641 //[over.best.ics]
642 struct Y { Y(int); }; //expected-note 3{{candidate}}
643 struct A { operator int(this auto&&); };  //expected-note {{candidate}}
644 Y y1 = A();   // expected-error{{no viable conversion from 'A' to 'Y'}}
645 
646 struct X { X(); }; //expected-note 3{{candidate}}
647 struct B { operator X(this auto&&); };
648 B b;
649 X x{{b}}; // expected-error{{no matching constructor for initialization of 'X'}}
650 
651 struct T{}; // expected-note 2{{candidate constructor}}
652 struct C {
653     operator T (this int); // expected-note {{candidate function not viable: no known conversion from 'C' to 'int' for object argument}}
654     operator int() const; // expected-note {{candidate function}}
655 };
656 
657 void foo(C c) {
658    T d = c; // expected-error {{no viable conversion from 'C' to 'T'}}
659 }
660 
661 }
662 
663 namespace surrogate {
664 using fn_t = void();
665 struct C {
666     operator fn_t * (this C const &);
667 };
668 
669 void foo(C c) {
670    c();
671 }
672 
673 }
674 
675 
676 namespace GH69838 {
677 struct S {
678   S(this auto &self) {} // expected-error {{an explicit object parameter cannot appear in a constructor}}
679   virtual void f(this S self) {} // expected-error {{an explicit object parameter cannot appear in a virtual function}}
680   void g(this auto &self) const {} // expected-error {{explicit object member function cannot have 'const' qualifier}}
681   void h(this S self = S{}) {} // expected-error {{the explicit object parameter cannot have a default argument}}
682   void i(int i, this S self = S{}) {} // expected-error {{an explicit object parameter can only appear as the first parameter of the function}}
683   ~S(this S &&self); // expected-error {{an explicit object parameter cannot appear in a destructor}} \
684                      // expected-error {{destructor cannot have any parameters}}
685 
686   static void j(this S s); // expected-error {{an explicit object parameter cannot appear in a static function}}
687 };
688 
689 void nonmember(this S s); // expected-error {{an explicit object parameter cannot appear in a non-member function}}
690 
691 int test() {
692   S s;
693   s.f();
694   s.g();
695   s.h();
696   s.i(0);
697   s.j({});
698   nonmember(S{});
699 }
700 
701 }
702 
703 namespace GH69962 {
704 struct S {
705     S(const S&);
706 };
707 
708 struct Thing {
709     template<typename Self, typename ... Args>
710     Thing(this Self&& self, Args&& ... args) { } // expected-error {{an explicit object parameter cannot appear in a constructor}}
711 };
712 
713 class Server : public Thing {
714     S name_;
715 };
716 }
717 
718 namespace GH69233 {
719 struct Base {};
720 struct S : Base {
721     int j;
722     S& operator=(this Base& self, const S&) = default;
723     // expected-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
724     // expected-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
725     // expected-note@-3 {{explicitly defaulted function was implicitly deleted here}}
726 };
727 
728 struct S2 {
729     S2& operator=(this int&& self, const S2&);
730     S2& operator=(this int&& self, S2&&);
731     operator int();
732 };
733 
734 S2& S2::operator=(this int&& self, const S2&) = default;
735 // expected-error@-1 {{the type of the explicit object parameter of an explicitly-defaulted copy assignment operator should be reference to 'S2'}}
736 
737 S2& S2::operator=(this int&& self, S2&&) = default;
738 // expected-error@-1 {{the type of the explicit object parameter of an explicitly-defaulted move assignment operator should be reference to 'S2'}}
739 
740 struct Move {
741     Move& operator=(this int&, Move&&) = default;
742     // expected-warning@-1 {{explicitly defaulted move assignment operator is implicitly deleted}}
743     // expected-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit move assignment operator}}
744     // expected-note@-3 {{copy assignment operator is implicitly deleted because 'Move' has a user-declared move assignment operator}}
745 };
746 
747 void test() {
748     S s;
749     s = s; // expected-error {{object of type 'S' cannot be assigned because its copy assignment operator is implicitly deleted}}
750     S2 s2;
751     s2 = s2;
752 
753     Move m;
754     m = Move{}; // expected-error {{object of type 'Move' cannot be assigned because its copy assignment operator is implicitly deleted}}
755 }
756 
757 }
758 
759 
760 namespace GH75732 {
761 auto serialize(auto&& archive, auto&& c){ }
762 struct D {
763     auto serialize(this auto&& self, auto&& archive) {
764         serialize(archive, self); // expected-error {{call to explicit member function without an object argument}}
765     }
766 };
767 }
768 
769 namespace GH80971 {
770 struct S {
771   auto f(this auto self...) {  }
772 };
773 
774 int bug() {
775   S{}.f(0);
776 }
777 }
778 
779 namespace GH84163 {
780 struct S {
781   int x;
782 
783   auto foo() {
784     return [*this](this auto&&) {
785       x = 10; // expected-error {{read-only variable is not assignable}}
786     };
787   }
788 };
789 
790 int f() {
791   S s{ 5 };
792   const auto l = s.foo();
793   l(); // expected-note {{in instantiation of}}
794 
795   const auto g = [x = 10](this auto&& self) { x = 20; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
796   g(); // expected-note {{in instantiation of}}
797 }
798 }
799 
800 namespace GH86054 {
801 template<typename M>
802 struct unique_lock {
803   unique_lock(M&) {}
804 };
805 int f() {
806   struct mutex {} cursor_guard;
807   [&cursor_guard](this auto self) {
808     unique_lock a(cursor_guard);
809   }();
810 }
811 }
812 
813 namespace GH86398 {
814 struct function {}; // expected-note 2 {{not viable}}
815 int f() {
816   function list;
817   [&list](this auto self) {
818     list = self; // expected-error {{no viable overloaded '='}}
819   }(); // expected-note {{in instantiation of}}
820 }
821 
822 struct function2 {
823   function2& operator=(function2 const&) = delete; // expected-note {{candidate function not viable}}
824 };
825 int g() {
826   function2 list;
827   [&list](this auto self) {
828     list = self; // expected-error {{no viable overloaded '='}}
829   }(); // expected-note {{in instantiation of}}
830 }
831 
832 struct function3 {
833   function3& operator=(function3 const&) = delete; // expected-note {{has been explicitly deleted}}
834 };
835 int h() {
836   function3 list;
837   [&list](this auto self) {
838     list = function3{}; // expected-error {{selected deleted operator '='}}
839   }();
840 }
841 }
842 
843 namespace GH92188 {
844 struct A {
845   template<auto N>
846   void operator+=(this auto &&, const char (&)[N]);
847   void operator+=(this auto &&, auto &&) = delete;
848 
849   void f1(this A &, auto &);
850   void f1(this A &, auto &&) = delete;
851 
852   void f2(this auto&);
853   void f2(this auto&&) = delete;
854 
855   void f3(auto&) &;
856   void f3(this A&, auto&&) = delete;
857 
858   void f4(auto&&) & = delete;
859   void f4(this A&, auto&);
860 
861   static void f5(auto&);
862   void f5(this A&, auto&&) = delete;
863 
864   static void f6(auto&&) = delete;
865   void f6(this A&, auto&);
866 
867   void implicit_this() {
868     int lval;
869     operator+=("123");
870     f1(lval);
871     f2();
872     f3(lval);
873     f4(lval);
874     f5(lval);
875     f6(lval);
876   }
877 
878   void operator-(this A&, auto&&) = delete;
879   friend void operator-(A&, auto&);
880 
881   void operator*(this A&, auto&);
882   friend void operator*(A&, auto&&) = delete;
883 };
884 
885 void g() {
886   A a;
887   int lval;
888   a += "123";
889   a.f1(lval);
890   a.f2();
891   a.f3(lval);
892   a.f4(lval);
893   a.f5(lval);
894   a.f6(lval);
895   a - lval;
896   a * lval;
897 }
898 }
899 
900 namespace P2797 {
901 
902 int bar(void) { return 55; }
903 int (&fref)(void) = bar;
904 
905 struct C {
906   void c(this const C&);    // #first
907   void c() &;               // #second
908   static void c(int = 0);   // #third
909 
910   void d() {
911     c();                // expected-error {{call to member function 'c' is ambiguous}}
912                         // expected-note@#first {{candidate function}}
913                         // expected-note@#second {{candidate function}}
914                         // expected-note@#third {{candidate function}}
915 
916     (C::c)();           // expected-error {{call to member function 'c' is ambiguous}}
917                         // expected-note@#first {{candidate function}}
918                         // expected-note@#second {{candidate function}}
919                         // expected-note@#third {{candidate function}}
920 
921     (&(C::c))();        // expected-error {{cannot create a non-constant pointer to member function}}
922     (&C::c)(C{});
923     (&C::c)(*this);     // expected-error {{call to non-static member function without an object argument}}
924     (&C::c)();
925 
926     (&fref)();
927   }
928 };
929 }
930 
931 namespace GH85992 {
932 namespace N {
933 struct A {
934   int f(this A);
935 };
936 
937 int f(A);
938 }
939 
940 struct S {
941   int (S::*x)(this int); // expected-error {{an explicit object parameter can only appear as the first parameter of a member function}}
942   int (*y)(this int); // expected-error {{an explicit object parameter can only appear as the first parameter of a member function}}
943   int (***z)(this int); // expected-error {{an explicit object parameter can only appear as the first parameter of a member function}}
944 
945   int f(this S);
946   int ((g))(this S);
947   friend int h(this S); // expected-error {{an explicit object parameter cannot appear in a non-member function}}
948   int h(int x, int (*)(this S)); // expected-error {{an explicit object parameter can only appear as the first parameter of a member function}}
949 
950   struct T {
951     int f(this T);
952   };
953 
954   friend int T::f(this T);
955   friend int N::A::f(this N::A);
956   friend int N::f(this N::A); // expected-error {{an explicit object parameter cannot appear in a non-member function}}
957   int friend func(this T); // expected-error {{an explicit object parameter cannot appear in a non-member function}}
958 };
959 
960 using T = int (*)(this int); // expected-error {{an explicit object parameter can only appear as the first parameter of a member function}}
961 using U = int (S::*)(this int); // expected-error {{an explicit object parameter can only appear as the first parameter of a member function}}
962 int h(this int); // expected-error {{an explicit object parameter cannot appear in a non-member function}}
963 
964 int S::f(this S) { return 1; }
965 
966 namespace a {
967 void f();
968 };
969 void a::f(this auto) {} // expected-error {{an explicit object parameter cannot appear in a non-member function}}
970 }
971 
972 namespace GH100341 {
973 struct X {
974     X() = default;
975     X(X&&) = default;
976     void operator()(this X);
977 };
978 
979 void fail() {
980     X()();
981     [x = X{}](this auto) {}();
982 }
983 void pass() {
984     std::move(X())();
985     std::move([x = X{}](this auto) {})();
986 }
987 } // namespace GH100341
988 struct R {
989   void f(this auto &&self, int &&r_value_ref) {} // expected-note {{candidate function template not viable: expects an rvalue for 2nd argument}}
990   void g(int &&r_value_ref) {
991 	f(r_value_ref); // expected-error {{no matching member function for call to 'f'}}
992   }
993 };
994 
995 namespace GH100329 {
996 struct A {
997     bool operator == (this const int&, const A&);
998 };
999 bool A::operator == (this const int&, const A&) = default;
1000 // expected-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'const int &', expected 'const GH100329::A &'}}
1001 } // namespace GH100329
1002 
1003 namespace defaulted_assign {
1004 struct A {
1005   A& operator=(this A, const A&) = default;
1006   // expected-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
1007   // expected-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
1008   A& operator=(this int, const A&) = default;
1009   // expected-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
1010   // expected-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
1011 };
1012 } // namespace defaulted_assign
1013 
1014 namespace defaulted_compare {
1015 struct A {
1016   bool operator==(this A&, const A&) = default;
1017   // expected-error@-1 {{defaulted member equality comparison operator must be const-qualified}}
1018   bool operator==(this const A, const A&) = default;
1019   // expected-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'const A', expected 'const defaulted_compare::A &'}}
1020   bool operator==(this A, A) = default;
1021 };
1022 struct B {
1023   int a;
1024   bool operator==(this B, B) = default;
1025 };
1026 static_assert(B{0} == B{0});
1027 static_assert(B{0} != B{1});
1028 template<B b>
1029 struct X;
1030 static_assert(__is_same(X<B{0}>, X<B{0}>));
1031 static_assert(!__is_same(X<B{0}>, X<B{1}>));
1032 } // namespace defaulted_compare
1033 
1034 namespace static_overloaded_operator {
1035 struct A {
1036   template<auto N>
1037   static void operator()(const char (&)[N]);
1038   void operator()(this auto &&, auto &&);
1039 
1040   void implicit_this() {
1041     operator()("123");
1042   }
1043 };
1044 
1045 struct B {
1046   template<auto N>
1047   void operator()(this auto &&, const char (&)[N]);
1048   static void operator()(auto &&);
1049 
1050   void implicit_this() {
1051     operator()("123");
1052   }
1053 };
1054 
1055 struct C {
1056   template<auto N>
1057   static void operator[](const char (&)[N]);
1058   void operator[](this auto &&, auto &&);
1059 
1060   void implicit_this() {
1061     operator[]("123");
1062   }
1063 };
1064 
1065 struct D {
1066   template<auto N>
1067   void operator[](this auto &&, const char (&)[N]);
1068   static void operator[](auto &&);
1069 
1070   void implicit_this() {
1071     operator[]("123");
1072   }
1073 };
1074 
1075 } // namespace static_overloaded_operator
1076 
1077 namespace GH102025 {
1078 struct Foo {
1079   template <class T>
1080   constexpr auto operator[](this T &&self, auto... i) // expected-note {{candidate template ignored: substitution failure [with T = Foo &, i:auto = <>]: member '_evaluate' used before its declaration}}
1081       -> decltype(_evaluate(self, i...)) {
1082     return self._evaluate(i...);
1083   }
1084 
1085 private:
1086   template <class T>
1087   constexpr auto _evaluate(this T &&self, auto... i) -> decltype((i + ...));
1088 };
1089 
1090 int main() {
1091   Foo foo;
1092   return foo[]; // expected-error {{no viable overloaded operator[] for type 'Foo'}}
1093 }
1094 }
1095 
1096 namespace GH100394 {
1097 struct C1 {
1098   void f(this const C1);
1099   void f() const;        // ok
1100 };
1101 
1102 struct C2 {
1103   void f(this const C2);    // expected-note {{previous declaration is here}}
1104   void f(this volatile C2); // expected-error {{class member cannot be redeclared}} \
1105                             // expected-warning {{volatile-qualified parameter type 'volatile C2' is deprecated}}
1106 };
1107 
1108 struct C3 {
1109   void f(this volatile C3); // expected-note {{previous declaration is here}} \
1110                             // expected-warning {{volatile-qualified parameter type 'volatile C3' is deprecated}}
1111   void f(this const C3);    // expected-error {{class member cannot be redeclared}}
1112 };
1113 
1114 struct C4 {
1115   void f(this const C4);          // expected-note {{previous declaration is here}}
1116   void f(this const volatile C4); // expected-error {{class member cannot be redeclared}} \
1117                                   // expected-warning {{volatile-qualified parameter type 'const volatile C4' is deprecated}}
1118 };
1119 }
1120 
1121 
1122 namespace GH112559 {
1123 struct Wrap  {};
1124 struct S {
1125     constexpr operator Wrap (this const S& self) {
1126         return Wrap{};
1127     };
1128     constexpr int operator <<(this Wrap self, int i) {
1129         return 0;
1130     }
1131 };
1132 // Purposefully invalid expression to check an assertion in the
1133 // expression recovery machinery.
1134 static_assert((S{} << 11) == a);
1135 // expected-error@-1 {{use of undeclared identifier 'a'}}
1136 }
1137