https://github.com/philnik777 created 
https://github.com/llvm/llvm-project/pull/200689

Fixes #118166


>From c0ef211fa6a07baa4f24ab23837aa06641acd10c Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <[email protected]>
Date: Sun, 31 May 2026 22:21:36 +0200
Subject: [PATCH] [Clang] Accept deducing this as an extension pre-C++23

---
 .../clang/Basic/DiagnosticSemaKinds.td        |   4 +-
 clang/lib/Sema/SemaDecl.cpp                   |   3 +-
 clang/test/CXX/drs/cwg25xx.cpp                |  28 +-
 clang/test/CXX/drs/cwg26xx.cpp                |  18 +-
 clang/test/CXX/special/class.copy/p25-0x.cpp  |   1 +
 .../CodeGenCXX/cxx2b-deducing-this-cc.cpp     |   1 +
 clang/test/CodeGenCXX/cxx2b-deducing-this.cpp |   1 +
 .../CodeGenCXX/cxx2b-mangle-deducing-this.cpp |   1 +
 ...crosoft-abi-explicit-object-parameters.cpp |   1 +
 .../SemaCXX/cxx2b-deducing-this-compat.cpp    |   9 -
 .../SemaCXX/cxx2b-deducing-this-constexpr.cpp |  11 +-
 .../test/SemaCXX/cxx2b-deducing-this-coro.cpp |   1 +
 clang/test/SemaCXX/cxx2b-deducing-this.cpp    | 646 ++++++++++--------
 13 files changed, 413 insertions(+), 312 deletions(-)
 delete mode 100644 clang/test/SemaCXX/cxx2b-deducing-this-compat.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 077aace321264..a801159ee33d3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8185,8 +8185,8 @@ def err_compound_qualified_function_type : Error<
 def err_qualified_function_typeid : Error<
   "type operand %0 of 'typeid' cannot have '%1' qualifier">;
 
-def err_cxx20_deducing_this  : Error<
-  "explicit object parameters are incompatible with C++ standards before 
C++2b">;
+def ext_deducing_this  : ExtWarn<
+  "explicit object parameters are a C++23 extension">, InGroup<CXX23>;
 def err_explicit_object_default_arg: Error<
   "the explicit object parameter cannot have a default argument">;
 def err_explicit_object_parameter_pack: Error<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cddcf3a010279..d0f78f6725ecb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15666,8 +15666,7 @@ static void CheckExplicitObjectParameter(Sema &S, 
ParmVarDecl *P,
   assert(S.getLangOpts().CPlusPlus &&
          "explicit parameter in non-cplusplus mode");
   if (!S.getLangOpts().CPlusPlus23)
-    S.Diag(ExplicitThisLoc, diag::err_cxx20_deducing_this)
-        << P->getSourceRange();
+    S.Diag(ExplicitThisLoc, diag::ext_deducing_this) << P->getSourceRange();
 
   // C++2b [dcl.fct/7] An explicit object parameter shall not be a function
   // parameter pack.
diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index d5219bcd74756..f0e0cfc93b5e3 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives -verify=expected
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives 
-verify=expected,cxx11-14,since-cxx11
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives 
-verify=expected,cxx11-14,since-cxx11
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives 
-verify=expected,since-cxx11
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives 
-verify=expected,since-cxx11,since-cxx20
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives 
-verify=expected,since-cxx11,since-cxx20,since-cxx23
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives 
-verify=expected,since-cxx11,since-cxx20,since-cxx23
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -Wno-c++23-extensions -verify-directives 
-verify=expected
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -Wno-c++23-extensions -verify-directives 
-verify=expected,cxx11-14,since-cxx11
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -Wno-c++23-extensions -verify-directives 
-verify=expected,cxx11-14,since-cxx11
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -Wno-c++23-extensions -verify-directives 
-verify=expected,since-cxx11
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -Wno-c++23-extensions -verify-directives 
-verify=expected,since-cxx11,since-cxx20
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors                       -verify-directives 
-verify=expected,since-cxx11,since-cxx20,since-cxx23
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors                       -verify-directives 
-verify=expected,since-cxx11,since-cxx20,since-cxx23
 
 namespace std {
 struct type_info{};
@@ -138,20 +138,18 @@ struct S2 {
 } // namespace cwg2547
 
 namespace cwg2553 { // cwg2553: 18 review 2023-07-14
-#if __cplusplus >= 202302L
 struct B {
-  virtual void f(this B&); 
-  // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a 
virtual function}}
+  virtual void f(this B&);
+  // expected-error@-1 {{an explicit object parameter cannot appear in a 
virtual function}}
   static void f(this B&);
-  // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a 
static function}}
+  // expected-error@-1 {{an explicit object parameter cannot appear in a 
static function}}
   virtual void g(); // #cwg2553-g
 };
 struct D : B {
   void g(this D&);
-  // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a 
virtual function}}
-  //   since-cxx23-note@#cwg2553-g {{overridden virtual function is here}}
+  // expected-error@-1 {{an explicit object parameter cannot appear in a 
virtual function}}
+  //   expected-note@#cwg2553-g {{overridden virtual function is here}}
 };
-#endif
 } // namespace cwg2553
 
 namespace cwg2554 { // cwg2554: 18 review 2021-12-10
@@ -188,7 +186,7 @@ struct C {
 void foo() {
     constexpr auto b = [](this C) { return 1; };
     // FIXME: closure type shouldn't have a conversion function to function
-    //        pointer, because explicit object parameter is present. 
+    //        pointer, because explicit object parameter is present.
     constexpr int (*fp)(C) = b;
     static_assert(fp(1) == 1);
     static_assert((&decltype(b)::operator())(1) == 1);
diff --git a/clang/test/CXX/drs/cwg26xx.cpp b/clang/test/CXX/drs/cwg26xx.cpp
index 45653743ae574..a6994cb2427f9 100644
--- a/clang/test/CXX/drs/cwg26xx.cpp
+++ b/clang/test/CXX/drs/cwg26xx.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -verify=expected,cxx98
-// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -verify=expected,since-cxx11,cxx11
-// RUN: %clang_cc1 -std=c++14 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -verify=expected,since-cxx11
-// RUN: %clang_cc1 -std=c++17 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -verify=expected,since-cxx11
-// RUN: %clang_cc1 -std=c++20 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -verify=expected,since-cxx11,since-cxx20
-// RUN: %clang_cc1 -std=c++23 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -verify=expected,since-cxx11,since-cxx20,since-cxx23
-// RUN: %clang_cc1 -std=c++2c -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -verify=expected,since-cxx11,since-cxx20,since-cxx23
+// RUN: %clang_cc1 -std=c++98 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -Wno-c++23-extensions -verify=expected,cxx98
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -Wno-c++23-extensions -verify=expected,since-cxx11,cxx11
+// RUN: %clang_cc1 -std=c++14 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -Wno-c++23-extensions -verify=expected,since-cxx11
+// RUN: %clang_cc1 -std=c++17 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -Wno-c++23-extensions -verify=expected,since-cxx11
+// RUN: %clang_cc1 -std=c++20 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives -Wno-c++23-extensions 
-verify=expected,since-cxx11,since-cxx20
+// RUN: %clang_cc1 -std=c++23 -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives                       
-verify=expected,since-cxx11,since-cxx20,since-cxx23
+// RUN: %clang_cc1 -std=c++2c -fexceptions -fcxx-exceptions -pedantic-errors 
%s -verify-directives                       
-verify=expected,since-cxx11,since-cxx20,since-cxx23
 
 #if __cplusplus == 199711L
 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
@@ -256,12 +256,10 @@ int i0 = f<X>(0);
 } // namespace cwg2650
 
 namespace cwg2653 { // cwg2653: 18
-#if __cplusplus >= 202302L
   struct Test { void f(this const auto& = Test{}); };
   // since-cxx23-error@-1 {{the explicit object parameter cannot have a 
default argument}}
   auto L = [](this const auto& = Test{}){};
   // since-cxx23-error@-1 {{the explicit object parameter cannot have a 
default argument}}
-#endif
 } // namespace cwg2653
 
 namespace cwg2654 { // cwg2654: 16
@@ -335,7 +333,6 @@ void m() {
 } // namespace cwg2672
 
 namespace cwg2687 { // cwg2687: 18
-#if __cplusplus >= 202302L
 struct S{
     void f(int);
     static void g(int);
@@ -348,7 +345,6 @@ void test() {
     (&S::g)(1);
     (&S::h)(S(), 1);
 }
-#endif
 } // namespace cwg2687
 
 namespace cwg2692 { // cwg2692: 19
diff --git a/clang/test/CXX/special/class.copy/p25-0x.cpp 
b/clang/test/CXX/special/class.copy/p25-0x.cpp
index c13c686bd6b54..6892598d88373 100644
--- a/clang/test/CXX/special/class.copy/p25-0x.cpp
+++ b/clang/test/CXX/special/class.copy/p25-0x.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins
 // RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins 
-fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -DDEDUCING_THIS 
-Wno-deprecated-builtins -Wno-c++23-extensions  %s -verify
 // RUN: %clang_cc1 -fsyntax-only -std=c++2b -DDEDUCING_THIS 
-Wno-deprecated-builtins  %s -verify
 
 // expected-no-diagnostics
diff --git a/clang/test/CodeGenCXX/cxx2b-deducing-this-cc.cpp 
b/clang/test/CodeGenCXX/cxx2b-deducing-this-cc.cpp
index bfbb24fcf23d9..6f53a864383d3 100644
--- a/clang/test/CodeGenCXX/cxx2b-deducing-this-cc.cpp
+++ b/clang/test/CodeGenCXX/cxx2b-deducing-this-cc.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -triple i386-windows-msvc -o - | 
FileCheck %s
 // RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple i386-windows-msvc -o - | 
FileCheck %s
 
 namespace CC {
diff --git a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp 
b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
index 9664a866376ae..a169015ff09a8 100644
--- a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -std=c++17 -Wno-c++23-extensions %s -emit-llvm -triple 
x86_64-linux -o - | FileCheck %s
 // RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | 
FileCheck %s
 
 struct TrivialStruct {
diff --git a/clang/test/CodeGenCXX/cxx2b-mangle-deducing-this.cpp 
b/clang/test/CodeGenCXX/cxx2b-mangle-deducing-this.cpp
index 579e757e36fc8..573dea92241b2 100644
--- a/clang/test/CodeGenCXX/cxx2b-mangle-deducing-this.cpp
+++ b/clang/test/CodeGenCXX/cxx2b-mangle-deducing-this.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -std=c++20 -emit-llvm -triple x86_64-linux -o - %s | 
FileCheck %s
 // RUN: %clang_cc1 -std=c++2b -emit-llvm -triple x86_64-linux -o - %s 
2>/dev/null | FileCheck %s
 
 struct S {
diff --git a/clang/test/CodeGenCXX/microsoft-abi-explicit-object-parameters.cpp 
b/clang/test/CodeGenCXX/microsoft-abi-explicit-object-parameters.cpp
index 8abd7e04b597a..769e14e0c1af8 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-explicit-object-parameters.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-explicit-object-parameters.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -std=c++20 -emit-llvm -triple=x86_64-pc-win32 -o - %s 
2>/dev/null | FileCheck %s
 // RUN: %clang_cc1 -std=c++2b -emit-llvm -triple=x86_64-pc-win32 -o - %s 
2>/dev/null | FileCheck %s
 
 struct S {
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this-compat.cpp 
b/clang/test/SemaCXX/cxx2b-deducing-this-compat.cpp
deleted file mode 100644
index 32406dfcac425..0000000000000
--- a/clang/test/SemaCXX/cxx2b-deducing-this-compat.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++20 %s -verify
-
-struct S {
-    void f(this auto &a); // expected-error {{explicit object parameters are 
incompatible with C++ standards before C++2b}}
-};
-
-void f() {
-    (void)[](this auto&a){}; // expected-error {{explicit object parameters 
are incompatible with C++ standards before C++2b}}
-}
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp 
b/clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp
index 5b06c7d1827a7..ba8a90ad73e30 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++2b %s -verify
-// RUN: %clang_cc1 -fsyntax-only -std=c++2b %s -verify 
-fexperimental-new-constant-interpreter
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 %s -verify=cxx20 
-Wno-c++23-extensions
+// RUN: %clang_cc1 -fsyntax-only -std=c++2b %s -verify=cxx23
+// RUN: %clang_cc1 -fsyntax-only -std=c++2b %s -verify=cxx23 
-fexperimental-new-constant-interpreter
+// cxx23-no-diagnostics
 
 template <typename Base>
 struct Wrap : Base {
@@ -14,7 +15,7 @@ struct S {
     constexpr int f(this const S&, auto&&... args) {
         return (args + ... + 0);
     }
-    constexpr int operator[](this const S&) {
+    constexpr int operator[](this const S&) { // cxx20-error {{overloaded 
'operator[]' cannot have no parameter before C++23}}
         return 42;
     }
     constexpr int operator[](this const S& self, int i) {
@@ -45,7 +46,7 @@ struct S {
 consteval void test() {
     constexpr S s;
     static_assert(s.f() == 42);
-    static_assert(s[] == 42);
+    static_assert(s[] == 42); // cxx20-error {{expected expression}}
     static_assert(s[22] == 42);
     static_assert(s.f() == 42);
     static_assert(s() == 42);
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this-coro.cpp 
b/clang/test/SemaCXX/cxx2b-deducing-this-coro.cpp
index 88d95caf02563..cd3725dfc2d7b 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this-coro.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this-coro.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -std=c++20 %s -fsyntax-only -verify 
-Wno-coroutines-unsupported-target -Wno-c++23-extensions
 // RUN: %clang_cc1 -std=c++2b %s -fsyntax-only -verify 
-Wno-coroutines-unsupported-target
 
 #include "Inputs/std-coroutine.h"
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp 
b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
index b86731c7d7a11..390e6d5def544 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
@@ -1,40 +1,61 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++2b -Woverloaded-virtual %s -verify
-// RUN: %clang_cc1 -fsyntax-only -std=c++2b -Woverloaded-virtual %s -verify 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Woverloaded-virtual 
-verify=expected,cxx20 %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++2b -Woverloaded-virtual 
-verify=expectex,cxx23 %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++2b -Woverloaded-virtual 
-verify=expectex,cxx23 %s -verify -fexperimental-new-constant-interpreter
 
 
 // FIXME: can we improve these diagnostics?
 void f(this); // expected-error{{variable has incomplete type 'void'}} \
               // expected-error{{invalid use of 'this' outside of a non-static 
member function}}
 
-void g(this auto); // expected-error{{an explicit object parameter cannot 
appear in a non-member function}}
+void g(this auto); // expected-error{{an explicit object parameter cannot 
appear in a non-member function}} \
+                   // cxx20-warning {{explicit object parameters are a C++23 
extension}}
 
-auto l1 = [] (this auto) static {}; // expected-error{{an explicit object 
parameter cannot appear in a static lambda}}
-auto l2 = [] (this auto) mutable {}; // expected-error{{a lambda with an 
explicit object parameter cannot be mutable}}
-auto l3 = [](this auto...){}; // expected-error {{the explicit object 
parameter cannot be a function parameter pack}}
-auto l4 = [](int, this auto){}; // expected-error {{an explicit object 
parameter can only appear as the first parameter of the lambda}}
+auto l1 = [] (this auto) static {}; // expected-error{{an explicit object 
parameter cannot appear in a static lambda}} \
+                                    // cxx20-warning {{explicit object 
parameters are a C++23 extension}} \
+                                    // cxx20-warning {{static lambdas are a 
C++23 extension}}
+auto l2 = [] (this auto) mutable {}; // expected-error{{a lambda with an 
explicit object parameter cannot be mutable}} \
+                                     // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+auto l3 = [](this auto...){}; // expected-error {{the explicit object 
parameter cannot be a function parameter pack}} \
+                              // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+auto l4 = [](int, this auto){}; // expected-error {{an explicit object 
parameter can only appear as the first parameter of the lambda}} \
+                                // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
 
 struct S {
-    static void f(this auto); // expected-error{{an explicit object parameter 
cannot appear in a static function}}
-    virtual void f(this S); // expected-error{{an explicit object parameter 
cannot appear in a virtual function}}
+    static void f(this auto); // expected-error{{an explicit object parameter 
cannot appear in a static function}} \
+                              // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+    virtual void f(this S); // expected-error{{an explicit object parameter 
cannot appear in a virtual function}} \
+                            // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
 
     // new and delete are implicitly static
-    void *operator new(this unsigned long); // expected-error{{an explicit 
object parameter cannot appear in a static function}}
-    void operator delete(this void*); // expected-error{{an explicit object 
parameter cannot appear in a static function}}
-
-    void g(this auto) const; // expected-error{{explicit object member 
function cannot have 'const' qualifier}}
-    void h(this auto) &; // expected-error{{explicit object member function 
cannot have '&' qualifier}}
-    void i(this auto) &&; // expected-error{{explicit object member function 
cannot have '&&' qualifier}}
-    void j(this auto) volatile; // expected-error{{explicit object member 
function cannot have 'volatile' qualifier}}
-    void k(this auto) __restrict; // expected-error{{explicit object member 
function cannot have '__restrict' qualifier}}
-    void l(this auto) _Nonnull; // expected-error{{explicit object member 
function cannot have '' qualifie}}
-
-
-    void variadic(this auto...); // expected-error{{the explicit object 
parameter cannot be a function parameter pack}}
-    void not_first(int, this auto); // expected-error {{an explicit object 
parameter can only appear as the first parameter of the function}}
-
-    S(this auto); // expected-error {{an explicit object parameter cannot 
appear in a constructor}}
+    void *operator new(this unsigned long); // expected-error{{an explicit 
object parameter cannot appear in a static function}} \
+                                            // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void operator delete(this void*); // expected-error{{an explicit object 
parameter cannot appear in a static function}} \
+                                      // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+
+    void g(this auto) const; // expected-error{{explicit object member 
function cannot have 'const' qualifier}} \
+                             // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
+    void h(this auto) &; // expected-error{{explicit object member function 
cannot have '&' qualifier}} \
+                         // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+    void i(this auto) &&; // expected-error{{explicit object member function 
cannot have '&&' qualifier}} \
+                          // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+    void j(this auto) volatile; // expected-error{{explicit object member 
function cannot have 'volatile' qualifier}} \
+                                // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+    void k(this auto) __restrict; // expected-error{{explicit object member 
function cannot have '__restrict' qualifier}} \
+                                  // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void l(this auto) _Nonnull; // expected-error{{explicit object member 
function cannot have '' qualifier}} \
+                                // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+
+
+    void variadic(this auto...); // expected-error{{the explicit object 
parameter cannot be a function parameter pack}} \
+                                 // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+    void not_first(int, this auto); // expected-error {{an explicit object 
parameter can only appear as the first parameter of the function}} \
+                                    // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+
+    S(this auto); // expected-error {{an explicit object parameter cannot 
appear in a constructor}} \
+                  // cxx20-warning {{explicit object parameters are a C++23 
extension}}
     ~S(this S) {} // expected-error {{an explicit object parameter cannot 
appear in a destructor}} \
-                  // expected-error {{destructor cannot have any parameters}}
+                  // expected-error {{destructor cannot have any parameters}} \
+                  // cxx20-warning {{explicit object parameters are a C++23 
extension}}
 };
 
 namespace Override {
@@ -46,28 +67,36 @@ struct A {
 
 // CWG2553
 struct B : A {
-    int f(this B&, int); // expected-warning {{hides overloaded virtual 
function}}
-    int f(this B&);  // expected-error {{an explicit object parameter cannot 
appear in a virtual function}}
-    int g(this B&); // expected-warning {{hides overloaded virtual function}}
-    int h(this B&); // expected-error {{an explicit object parameter cannot 
appear in a virtual function}}
-    int h(this B&&); // expected-error {{an explicit object parameter cannot 
appear in a virtual function}}
-    int h(this const B&&); // expected-error {{an explicit object parameter 
cannot appear in a virtual function}}
-    int h(this A&); // expected-error {{an explicit object parameter cannot 
appear in a virtual function}}
-    int h(this int); // expected-error {{an explicit object parameter cannot 
appear in a virtual function}}
+    int f(this B&, int); // expected-warning {{hides overloaded virtual 
function}} \
+                         // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+    int f(this B&);  // expected-error {{an explicit object parameter cannot 
appear in a virtual function}} \
+                     // cxx20-warning {{explicit object parameters are a C++23 
extension}}
+    int g(this B&); // expected-warning {{hides overloaded virtual function}} \
+                    // cxx20-warning {{explicit object parameters are a C++23 
extension}}
+    int h(this B&); // expected-error {{an explicit object parameter cannot 
appear in a virtual function}} \
+                    // cxx20-warning {{explicit object parameters are a C++23 
extension}}
+    int h(this B&&); // expected-error {{an explicit object parameter cannot 
appear in a virtual function}} \
+                     // cxx20-warning {{explicit object parameters are a C++23 
extension}}
+    int h(this const B&&); // expected-error {{an explicit object parameter 
cannot appear in a virtual function}} \
+                           // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+    int h(this A&); // expected-error {{an explicit object parameter cannot 
appear in a virtual function}} \
+                    // cxx20-warning {{explicit object parameters are a C++23 
extension}}
+    int h(this int); // expected-error {{an explicit object parameter cannot 
appear in a virtual function}} \
+                     // cxx20-warning {{explicit object parameters are a C++23 
extension}}
 };
 }
 
 namespace DefaultArgs {
-     struct Test { void f(this const auto& = Test{}); };
+     struct Test { void f(this const auto& = Test{}); }; // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
     // expected-error@-1 {{the explicit object parameter cannot have a default 
argument}}
-    auto L = [](this const auto& = Test{}){};
+    auto L = [](this const auto& = Test{}){}; // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
     // expected-error@-1 {{the explicit object parameter cannot have a default 
argument}}
 }
 
 struct CannotUseThis {
     int fun();
     int m;
-    void f(this auto) {
+    void f(this auto) { // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
         this->fun(); // expected-error{{invalid use of 'this' in a function 
with an explicit object parameter}}
         fun(); // expected-error {{call to non-static member function without 
an object argument}}
         m = 0; // expected-error {{invalid use of member 'm' in explicit 
object member function}}
@@ -81,7 +110,7 @@ struct CannotUseThisBase {
 };
 
 struct CannotUseThisDerived : CannotUseThisBase {
-  void bar(this auto) {
+  void bar(this auto) { // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
     foo(); // expected-error {{call to non-static member function without an 
object argument}}
     n = 12; // expected-error {{invalid use of member 'n' in explicit object 
member function}}
     i = 100;
@@ -96,12 +125,12 @@ struct Test {
 
 void test() {
 
-    [i = 0](this Test) { }();
+    [i = 0](this Test) { }(); // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
     // expected-error@-1 {{invalid explicit object parameter type 'Test' in 
lambda with capture; the type must be the same as, or derived from, the lambda}}
 
     struct Derived;
-    auto ok = [i = 0](this const Derived&) {};
-    auto ko = [i = 0](this const Test&) {};
+    auto ok = [i = 0](this const Derived&) {}; // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+    auto ko = [i = 0](this const Test&) {};    // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
     // expected-error@-1 {{invalid explicit object parameter type 'Test' in 
lambda with capture; the type must be the same as, or derived from, the lambda}}
 
     struct Derived : decltype(ok){};
@@ -112,12 +141,13 @@ void test() {
     DerivedErr dko{ko};
     dko();
 
-    auto alsoOk = [](this const Test &) {};
+    auto alsoOk = [](this const Test &) {}; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     alsoOk();
 }
 
 struct Frobble;
-auto nothingIsOkay = [i = 0](this const Frobble &) {};  // expected-note 
{{candidate function not viable: requires 0 non-object arguments, but 1 was 
provided}}
+auto nothingIsOkay = [i = 0](this const Frobble &) {};  // expected-note 
{{candidate function not viable: requires 0 non-object arguments, but 1 was 
provided}} \
+                                                        // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
 struct Frobble {} f;
 void test2()  {
     nothingIsOkay(f); // expected-error {{no matching function for call to 
object of type}}
@@ -126,56 +156,68 @@ void test2()  {
 }
 
 struct Corresponding {
-    void a(this Corresponding&); // expected-note 2{{here}}
+    void a(this Corresponding&); // expected-note 2{{here}} \
+                                 // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
     void a(); // expected-error{{cannot be redeclared}}
     void a() &; // expected-error{{cannot be redeclared}}
-    void a(this Corresponding&, int);
-    void a(this Corresponding&, double);
+    void a(this Corresponding&, int);    // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void a(this Corresponding&, double); // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
-    void b(this const Corresponding&); // expected-note 2{{here}}
+    void b(this const Corresponding&); // expected-note 2{{here}} \
+                                       // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     void b() const; // expected-error{{cannot be redeclared}}
     void b() const &; // expected-error{{cannot be redeclared}}
 
-    void c(this Corresponding&&); // expected-note {{here}}
+    void c(this Corresponding&&); // expected-note {{here}} \
+                                  // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     void c() &&; // expected-error{{cannot be redeclared}}
 
-    void d(this Corresponding&);
-    void d(this Corresponding&&);
-    void d(this const Corresponding&);
-    void d(this const int&);
-    void d(this const int);  // expected-note {{previous declaration is here}}
-    void d(this int);        // expected-error {{class member cannot be 
redeclared}}
-
-    void e(this const Corresponding&&); // expected-note {{here}}
+    void d(this Corresponding&); // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+    void d(this Corresponding&&); // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void d(this const Corresponding&); // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void d(this const int&); // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
+    void d(this const int);  // expected-note {{previous declaration is here}} 
\
+                             // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
+    void d(this int);        // expected-error {{class member cannot be 
redeclared}} \
+                             // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
+
+    void e(this const Corresponding&&); // expected-note {{here}} \
+                                        // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     void e() const &&; // expected-error{{cannot be redeclared}}
 
 };
 
 template <typename T>
 struct CorrespondingTpl {
-    void a(this CorrespondingTpl&); // expected-note 2{{here}}
+    void a(this CorrespondingTpl&); // expected-note 2{{here}} \
+                                    // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     void a(); // expected-error{{cannot be redeclared}}
     void a() &; // expected-error{{cannot be redeclared}}
-    void a(this Corresponding&, int);
-    void a(this Corresponding&, double);
+    void a(this Corresponding&, int);    // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void a(this Corresponding&, double); // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     void a(long);
 
 
-    void b(this const CorrespondingTpl&); // expected-note 2{{here}}
+    void b(this const CorrespondingTpl&); // expected-note 2{{here}} \
+                                          // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     void b() const; // expected-error{{cannot be redeclared}}
     void b() const &; // expected-error{{cannot be redeclared}}
 
-    void c(this CorrespondingTpl&&); // expected-note {{here}}
+    void c(this CorrespondingTpl&&); // expected-note {{here}} \
+                                     // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     void c() &&; // expected-error{{cannot be redeclared}}
 
-    void d(this Corresponding&);
-    void d(this Corresponding&&);
-    void d(this const Corresponding&);
-    void d(this const int&);
-    void d(this const int); // expected-note {{previous declaration is here}}
-    void d(this int);       // expected-error {{class member cannot be 
redeclared}}
-    void e(this const CorrespondingTpl&&); // expected-note {{here}}
-    void e() const &&; // expected-error{{cannot be redeclared}}
+    void d(this Corresponding&);           // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void d(this Corresponding&&);          // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void d(this const Corresponding&);     // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void d(this const int&);               // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void d(this const int);                // expected-note {{previous 
declaration is here}} \
+                                           // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void d(this int);                      // expected-error {{class member 
cannot be redeclared}} \
+                                           // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void e(this const CorrespondingTpl&&); // expected-note {{here}} \
+                                           // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void e() const &&;                     // expected-error{{cannot be 
redeclared}}
 };
 
 struct C {
@@ -184,98 +226,116 @@ struct C {
 };
 
 void func(int i) {
-    (void)[=](this auto&&) { return i; }();
-    (void)[=](this const auto&) { return i; }();
-    (void)[i](this C) { return i; }(); // expected-error{{invalid explicit 
object parameter type 'C'}}
-    (void)[=](this C) { return i; }(); // expected-error{{invalid explicit 
object parameter type 'C'}}
-    (void)[](this C) { return 42; }();
-    auto l = [=](this auto&) {};
+    (void)[=](this auto&&) { return i; }();      // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+    (void)[=](this const auto&) { return i; }(); // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+    (void)[i](this C) { return i; }();           // expected-error{{invalid 
explicit object parameter type 'C'}} \
+                                                 // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+    (void)[=](this C) { return i; }();           // expected-error{{invalid 
explicit object parameter type 'C'}} \
+                                                 // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+    (void)[](this C) { return 42; }();           // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+    auto l = [=](this auto&) {};                 // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
     struct D : decltype(l) {};
     D d{l};
     d();
 }
 
 void TestMutationInLambda() {
-    [i = 0](this auto &&){ i++; }();
-    [i = 0](this auto){ i++; }();
-    [i = 0](this const auto&){ i++; }(); // expected-error {{cannot assign to 
a variable captured by copy in a non-mutable lambda}}
+    [i = 0](this auto &&){ i++; }();     // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    [i = 0](this auto){ i++; }();        // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    [i = 0](this const auto&){ i++; }(); // expected-error {{cannot assign to 
a variable captured by copy in a non-mutable lambda}} \
+                                         // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
     int x;
-    const auto l1 = [x](this auto&) { x = 42; }; // expected-error {{cannot 
assign to a variable captured by copy in a non-mutable lambda}}
-    const auto l2 = [=](this auto&) { x = 42; }; // expected-error {{cannot 
assign to a variable captured by copy in a non-mutable lambda}}
-
-    const auto l3 = [&x](this auto&) {
-        const auto l3a = [x](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+    const auto l1 = [x](this auto&) { x = 42; }; // expected-error {{cannot 
assign to a variable captured by copy in a non-mutable lambda}} \
+                                                 // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+    const auto l2 = [=](this auto&) { x = 42; }; // expected-error {{cannot 
assign to a variable captured by copy in a non-mutable lambda}} \
+                                                 // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+
+    const auto l3 = [&x](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        const auto l3a = [x](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}} \
+                                                      // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l3a(); // expected-note {{in instantiation of}}
     };
 
-    const auto l4 = [&x](this auto&) {
-        const auto l4a = [=](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+    const auto l4 = [&x](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        const auto l4a = [=](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}} \
+                                                      // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l4a(); // expected-note {{in instantiation of}}
     };
 
-    const auto l5 = [x](this auto&) {
-        const auto l5a = [x](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+    const auto l5 = [x](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        const auto l5a = [x](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}} \
+                                                      // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l5a(); // expected-note {{in instantiation of}}
     };
 
-    const auto l6 = [=](this auto&) {
-        const auto l6a = [=](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+    const auto l6 = [=](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        const auto l6a = [=](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}} \
+                                                      // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l6a(); // expected-note {{in instantiation of}}
     };
 
-    const auto l7 = [x](this auto&) {
-        const auto l7a = [=](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+    const auto l7 = [x](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        const auto l7a = [=](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}} \
+                                                      // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l7a(); // expected-note {{in instantiation of}}
     };
 
-    const auto l8 = [=](this auto&) {
-        const auto l8a = [x](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+    const auto l8 = [=](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        const auto l8a = [x](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}} \
+                                                      // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l8a(); // expected-note {{in instantiation of}}
     };
 
-    const auto l9 = [&](this auto&) {
-        const auto l9a = [x](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+    const auto l9 = [&](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        const auto l9a = [x](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}} \
+                                                      // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l9a(); // expected-note {{in instantiation of}}
     };
 
-    const auto l10 = [&](this auto&) {
-        const auto l10a = [=](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+    const auto l10 = [&](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        const auto l10a = [=](this auto&) { x = 42; }; // expected-error 
{{cannot assign to a variable captured by copy in a non-mutable lambda}} \
+                                                       // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l10a(); // expected-note {{in instantiation of}}
     };
 
-    const auto l11 = [x](this auto&) {
-        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}}
+    const auto l11 = [x](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        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}} \
+                                                        // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l11a();
     };
 
-    const auto l12 = [x](this auto&) {
-        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}}
+    const auto l12 = [x](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        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}} \
+                                                       // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l12a();
     };
 
-    const auto l13 = [=](this auto&) {
-        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}}
+    const auto l13 = [=](this auto&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+        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}} \
+                                                        // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         l13a();
     };
 
     struct S {
         int x;
         auto f() {
-            return [*this] (this auto&&) {
+            return [*this] (this auto&&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
                 x = 42; // expected-error {{read-only variable is not 
assignable}}
                 [*this] () mutable { x = 42; } ();
-                [*this] (this auto&&) { x = 42; } ();
+                [*this] (this auto&&) { x = 42; } (); // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
                 [*this] () { x = 42; } (); // expected-error {{read-only 
variable is not assignable}}
-                const auto l = [*this] (this auto&&) { x = 42; }; // 
expected-error {{read-only variable is not assignable}}
+                const auto l = [*this] (this auto&&) { x = 42; }; // 
expected-error {{read-only variable is not assignable}} \
+                                                                  // 
cxx20-warning {{explicit object parameters are a C++23 extension}}
                 l(); // expected-note {{in instantiation of}}
 
                 struct T {
                     int x;
                     auto g() {
-                        return [&] (this auto&&) {
+                        return [&] (this auto&&) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
                             x = 42;
-                            const auto l = [*this] (this auto&&) { x = 42; }; 
// expected-error {{read-only variable is not assignable}}
+                            const auto l = [*this] (this auto&&) { x = 42; }; 
// expected-error {{read-only variable is not assignable}} \
+                                                                              
// cxx20-warning {{explicit object parameters are a C++23 extension}}
                             l(); // expected-note {{in instantiation of}}
                         };
                     }
@@ -305,14 +365,14 @@ void TestMutationInLambda() {
     l14(); // expected-note 3 {{in instantiation of}}
 
     {
-      const auto l1 = [&x](this auto&) { x = 42; };
-      const auto l2 = [&](this auto&) { x = 42; };
+      const auto l1 = [&x](this auto&) { x = 42; }; // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
+      const auto l2 = [&](this auto&) { x = 42; };  // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
       l1();
       l2();
     }
 
     // Check that we don't crash if the lambda has type sugar.
-    const auto l15 = [=](this auto&&) [[clang::annotate_type("foo")]] 
[[clang::annotate_type("bar")]] {
+    const auto l15 = [=](this auto&&) [[clang::annotate_type("foo")]] 
[[clang::annotate_type("bar")]] { // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
         return x;
     };
 
@@ -330,7 +390,8 @@ struct Over_Call_Func_Example {
         a(); // ok, (*this).a()
     }
 
-    void f(this const Over_Call_Func_Example&); // expected-note {{here}}
+    void f(this const Over_Call_Func_Example&); // expected-note {{here}} \
+                                                // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
     void g() const {
         f();       // ok: (*this).f()
         f(*this);  // expected-error{{too many non-object arguments to 
function call}}
@@ -343,47 +404,53 @@ struct Over_Call_Func_Example {
         Over_Call_Func_Example{}.f();   // ok
     }
 
-    void k(this int);
+    void k(this int); // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
     operator int() const;
-    void m(this const Over_Call_Func_Example& c) {
+    void m(this const Over_Call_Func_Example& c) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
         c.k();     // ok
     }
 };
 
 struct AmbiguousConversion {
-  void f(this int); // expected-note {{candidate function}}
-  void f(this float); // expected-note {{candidate function}}
+  void f(this int); // expected-note {{candidate function}} \
+                    // cxx20-warning {{explicit object parameters are a C++23 
extension}}
+  void f(this float); // expected-note {{candidate function}} \
+                      // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
 
   operator int() const;
   operator float() const;
 
-  void test(this const AmbiguousConversion &s) {
+  void test(this const AmbiguousConversion &s) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
     s.f(); // expected-error {{call to member function 'f' is ambiguous}}
   }
 };
 
 struct IntToShort {
-  void s(this short);
+  void s(this short); // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
   operator int() const;
-  void test(this const IntToShort &val) {
+  void test(this const IntToShort &val) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     val.s();
   }
 };
 
 struct ShortToInt {
-  void s(this int);
+  void s(this int); // cxx20-warning {{explicit object parameters are a C++23 
extension}}
   operator short() const;
-  void test(this const ShortToInt &val) {
+  void test(this const ShortToInt &val) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     val.s();
   }
 };
 
 namespace arity_diagnostics {
 struct S {
-    void f(this auto &&, auto, auto); // expected-note {{requires 2 non-object 
arguments, but 0 were provided}}
-    void g(this auto &&, auto, auto); // expected-note {{requires 2 non-object 
arguments, but 3 were provided}}
-    void h(this auto &&, int, int i = 0); // expected-note {{requires at least 
1 non-object argument, but 0 were provided}}
-    void i(this S&&, int); // expected-note 2{{declared here}}
+    void f(this auto &&, auto, auto); // expected-note {{requires 2 non-object 
arguments, but 0 were provided}} \
+                                      // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void g(this auto &&, auto, auto); // expected-note {{requires 2 non-object 
arguments, but 3 were provided}} \
+                                      // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void h(this auto &&, int, int i = 0); // expected-note {{requires at least 
1 non-object argument, but 0 were provided}} \
+                                          // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    void i(this S&&, int); // expected-note 2{{declared here}} \
+                           // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
 };
 
 int test() {
@@ -407,8 +474,8 @@ namespace AddressOf {
 
 struct s {
     static void f(int);
-    void f(this auto &&) {}
-    void g(this s &&) {};
+    void f(this auto &&) {} // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
+    void g(this s &&) {};   // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
 
     void test_qual() {
         using F = void(s&&);
@@ -456,51 +523,51 @@ template <template <typename> typename T>
 struct Wrap {
 void f();
 struct S {
-    operator int(this auto&& self) {
+    operator int(this auto&& self) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return 0;
     }
-    Wrap* operator->(this auto&& self) {
+    Wrap* operator->(this auto&& self) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return new Wrap();
     }
-    int operator[](this auto&& self, int) {
+    int operator[](this auto&& self, int) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return 0;
     }
-    int operator()(this auto&& self, int) {
+    int operator()(this auto&& self, int) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return 0;
     }
-    int operator++(this auto&& self, int) {
+    int operator++(this auto&& self, int) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return 0;
     }
-    int operator++(this auto&& self) {
+    int operator++(this auto&& self) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return 0;
     }
-    int operator--(this auto&& self, int) {
+    int operator--(this auto&& self, int) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return 0;
     }
-    int operator--(this auto&& self) {
+    int operator--(this auto&& self) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return 0;
     }
-    int operator*(this auto&& self) {
+    int operator*(this auto&& self) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return 0;
     }
-    bool operator==(this auto&& self, int) {
+    bool operator==(this auto&& self, int) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return false;
     }
-    bool operator<=>(this auto&& self, int) {
+    bool operator<=>(this auto&& self, int) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return false;
     }
-    bool operator<<(this auto&& self, int b) {
+    bool operator<<(this auto&& self, int b) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
         static_assert(is_same<decltype(self), typename T<S>::type>);
         return false;
     }
@@ -641,17 +708,19 @@ void test() {
 namespace conversions {
 //[over.best.ics]
 struct Y { Y(int); }; //expected-note 3{{candidate}}
-struct A { operator int(this auto&&); };  //expected-note {{candidate}}
+struct A { operator int(this auto&&); };  // expected-note {{candidate}} \
+                                          // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 Y y1 = A();   // expected-error{{no viable conversion from 'A' to 'Y'}}
 
 struct X { X(); }; //expected-note 3{{candidate}}
-struct B { operator X(this auto&&); };
+struct B { operator X(this auto&&); }; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 B b;
 X x{{b}}; // expected-error{{no matching constructor for initialization of 
'X'}}
 
 struct T{}; // expected-note 2{{candidate constructor}}
 struct C {
-    operator T (this int); // expected-note {{candidate function not viable: 
no known conversion from 'C' to 'int' for object argument}}
+    operator T (this int); // expected-note {{candidate function not viable: 
no known conversion from 'C' to 'int' for object argument}} \
+                           // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
     operator int() const; // expected-note {{candidate function}}
 };
 
@@ -664,7 +733,7 @@ void foo(C c) {
 namespace surrogate {
 using fn_t = void();
 struct C {
-    operator fn_t * (this C const &);
+    operator fn_t * (this C const &); // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 };
 
 void foo(C c) {
@@ -676,18 +745,26 @@ void foo(C c) {
 
 namespace GH69838 {
 struct S {
-  S(this auto &self) {} // expected-error {{an explicit object parameter 
cannot appear in a constructor}}
-  virtual void f(this S self) {} // expected-error {{an explicit object 
parameter cannot appear in a virtual function}}
-  void g(this auto &self) const {} // expected-error {{explicit object member 
function cannot have 'const' qualifier}}
-  void h(this S self = S{}) {} // expected-error {{the explicit object 
parameter cannot have a default argument}}
-  void i(int i, this S self = S{}) {} // expected-error {{an explicit object 
parameter can only appear as the first parameter of the function}}
+  S(this auto &self) {} // expected-error {{an explicit object parameter 
cannot appear in a constructor}} \
+                        // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+  virtual void f(this S self) {} // expected-error {{an explicit object 
parameter cannot appear in a virtual function}} \
+                                 // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+  void g(this auto &self) const {} // expected-error {{explicit object member 
function cannot have 'const' qualifier}} \
+                                   // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+  void h(this S self = S{}) {} // expected-error {{the explicit object 
parameter cannot have a default argument}} \
+                               // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+  void i(int i, this S self = S{}) {} // expected-error {{an explicit object 
parameter can only appear as the first parameter of the function}} \
+                                      // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
   ~S(this S &&self); // expected-error {{an explicit object parameter cannot 
appear in a destructor}} \
-                     // expected-error {{destructor cannot have any 
parameters}}
+                     // expected-error {{destructor cannot have any 
parameters}} \
+                     // cxx20-warning {{explicit object parameters are a C++23 
extension}}
 
-  static void j(this S s); // expected-error {{an explicit object parameter 
cannot appear in a static function}}
+  static void j(this S s); // expected-error {{an explicit object parameter 
cannot appear in a static function}} \
+                           // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
 };
 
-void nonmember(this S s); // expected-error {{an explicit object parameter 
cannot appear in a non-member function}}
+void nonmember(this S s); // expected-error {{an explicit object parameter 
cannot appear in a non-member function}} \
+                          // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
 
 int test() {
   S s;
@@ -708,7 +785,8 @@ struct S {
 
 struct Thing {
     template<typename Self, typename ... Args>
-    Thing(this Self&& self, Args&& ... args) { } // expected-error {{an 
explicit object parameter cannot appear in a constructor}}
+    Thing(this Self&& self, Args&& ... args) { } // expected-error {{an 
explicit object parameter cannot appear in a constructor}} \
+                                                 // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
 };
 
 class Server : public Thing {
@@ -720,26 +798,26 @@ namespace GH69233 {
 struct Base {};
 struct S : Base {
     int j;
-    S& operator=(this Base& self, const S&) = default;
+    S& operator=(this Base& self, const S&) = default; // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
     // expected-warning@-1 {{explicitly defaulted copy assignment operator is 
implicitly deleted}}
     // expected-note@-2 {{function is implicitly deleted because its declared 
type does not match the type of an implicit copy assignment operator}}
     // expected-note@-3 {{explicitly defaulted function was implicitly deleted 
here}}
 };
 
 struct S2 {
-    S2& operator=(this int&& self, const S2&);
-    S2& operator=(this int&& self, S2&&);
+    S2& operator=(this int&& self, const S2&); // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
+    S2& operator=(this int&& self, S2&&);      // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
     operator int();
 };
 
-S2& S2::operator=(this int&& self, const S2&) = default;
+S2& S2::operator=(this int&& self, const S2&) = default; // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
 // expected-error@-1 {{the type of the explicit object parameter of an 
explicitly-defaulted copy assignment operator should be reference to 'S2'}}
 
-S2& S2::operator=(this int&& self, S2&&) = default;
+S2& S2::operator=(this int&& self, S2&&) = default; // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
 // expected-error@-1 {{the type of the explicit object parameter of an 
explicitly-defaulted move assignment operator should be reference to 'S2'}}
 
 struct Move {
-    Move& operator=(this int&, Move&&) = default;
+    Move& operator=(this int&, Move&&) = default; // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
     // expected-warning@-1 {{explicitly defaulted move assignment operator is 
implicitly deleted}}
     // expected-note@-2 {{function is implicitly deleted because its declared 
type does not match the type of an implicit move assignment operator}}
     // expected-note@-3 {{copy assignment operator is implicitly deleted 
because 'Move' has a user-declared move assignment operator}}
@@ -761,7 +839,7 @@ void test() {
 namespace GH75732 {
 auto serialize(auto&& archive, auto&& c){ }
 struct D {
-    auto serialize(this auto&& self, auto&& archive) {
+    auto serialize(this auto&& self, auto&& archive) { // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         serialize(archive, self); // expected-error {{call to explicit member 
function without an object argument}}
     }
 };
@@ -769,7 +847,7 @@ struct D {
 
 namespace GH80971 {
 struct S {
-  auto f(this auto self...) {  }
+  auto f(this auto self...) {  } // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
 };
 
 int bug() {
@@ -782,7 +860,7 @@ struct S {
   int x;
 
   auto foo() {
-    return [*this](this auto&&) {
+    return [*this](this auto&&) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
       x = 10; // expected-error {{read-only variable is not assignable}}
     };
   }
@@ -793,7 +871,8 @@ int f() {
   const auto l = s.foo();
   l(); // expected-note {{in instantiation of}}
 
-  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}}
+  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}} \
+                                                         // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
   g(); // expected-note {{in instantiation of}}
 }
 }
@@ -805,7 +884,7 @@ struct unique_lock {
 };
 int f() {
   struct mutex {} cursor_guard;
-  [&cursor_guard](this auto self) {
+  [&cursor_guard](this auto self) { // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
     unique_lock a(cursor_guard);
   }();
 }
@@ -815,7 +894,7 @@ namespace GH86398 {
 struct function {}; // expected-note 2 {{not viable}}
 int f() {
   function list;
-  [&list](this auto self) {
+  [&list](this auto self) { // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
     list = self; // expected-error {{no viable overloaded '='}}
   }(); // expected-note {{in instantiation of}}
 }
@@ -825,7 +904,7 @@ struct function2 {
 };
 int g() {
   function2 list;
-  [&list](this auto self) {
+  [&list](this auto self) { // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
     list = self; // expected-error {{no viable overloaded '='}}
   }(); // expected-note {{in instantiation of}}
 }
@@ -835,7 +914,7 @@ struct function3 {
 };
 int h() {
   function3 list;
-  [&list](this auto self) {
+  [&list](this auto self) { // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
     list = function3{}; // expected-error {{selected deleted operator '='}}
   }();
 }
@@ -844,26 +923,26 @@ int h() {
 namespace GH92188 {
 struct A {
   template<auto N>
-  void operator+=(this auto &&, const char (&)[N]);
-  void operator+=(this auto &&, auto &&) = delete;
+  void operator+=(this auto &&, const char (&)[N]); // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
+  void operator+=(this auto &&, auto &&) = delete;  // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
 
-  void f1(this A &, auto &);
-  void f1(this A &, auto &&) = delete;
+  void f1(this A &, auto &);           // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+  void f1(this A &, auto &&) = delete; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
-  void f2(this auto&);
-  void f2(this auto&&) = delete;
+  void f2(this auto&);           // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+  void f2(this auto&&) = delete; // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
 
   void f3(auto&) &;
-  void f3(this A&, auto&&) = delete;
+  void f3(this A&, auto&&) = delete; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
   void f4(auto&&) & = delete;
-  void f4(this A&, auto&);
+  void f4(this A&, auto&); // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
 
   static void f5(auto&);
-  void f5(this A&, auto&&) = delete;
+  void f5(this A&, auto&&) = delete; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
   static void f6(auto&&) = delete;
-  void f6(this A&, auto&);
+  void f6(this A&, auto&); // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
 
   void implicit_this() {
     int lval;
@@ -876,10 +955,10 @@ struct A {
     f6(lval);
   }
 
-  void operator-(this A&, auto&&) = delete;
+  void operator-(this A&, auto&&) = delete; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
   friend void operator-(A&, auto&);
 
-  void operator*(this A&, auto&);
+  void operator*(this A&, auto&);             // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
   friend void operator*(A&, auto&&) = delete;
 };
 
@@ -904,7 +983,7 @@ int bar(void) { return 55; }
 int (&fref)(void) = bar;
 
 struct C {
-  void c(this const C&);    // #first
+  void c(this const C&);    // #first  cxx20-warning {{explicit object 
parameters are a C++23 extension}}
   void c() &;               // #second
   static void c(int = 0);   // #third
 
@@ -930,7 +1009,8 @@ struct C {
 
 struct CTpl {
   template <typename T>
-  constexpr int c(this const CTpl&, T) {  // #P2797-ctpl-1
+  constexpr int c(this const CTpl&, T) {  // #P2797-ctpl-1 \
+                                          // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
       return 42;
   }
 
@@ -959,62 +1039,74 @@ struct CTpl {
 namespace GH85992 {
 namespace N {
 struct A {
-  int f(this A);
+  int f(this A); // cxx20-warning {{explicit object parameters are a C++23 
extension}}
 };
 
 int f(A);
 }
 
 struct S {
-  int (S::*x)(this int); // expected-error {{an explicit object parameter can 
only appear as the first parameter of a member function}}
-  int (*y)(this int); // expected-error {{an explicit object parameter can 
only appear as the first parameter of a member function}}
-  int (***z)(this int); // expected-error {{an explicit object parameter can 
only appear as the first parameter of a member function}}
-
-  int f(this S);
-  int ((g))(this S);
-  friend int h(this S); // expected-error {{an explicit object parameter 
cannot appear in a non-member function}}
-  int h(int x, int (*)(this S)); // expected-error {{an explicit object 
parameter can only appear as the first parameter of a member function}}
+  int (S::*x)(this int); // expected-error {{an explicit object parameter can 
only appear as the first parameter of a member function}} \
+                         // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+  int (*y)(this int); // expected-error {{an explicit object parameter can 
only appear as the first parameter of a member function}} \
+                      // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+  int (***z)(this int); // expected-error {{an explicit object parameter can 
only appear as the first parameter of a member function}} \
+                        // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+
+  int f(this S);     // cxx20-warning {{explicit object parameters are a C++23 
extension}}
+  int ((g))(this S); // cxx20-warning {{explicit object parameters are a C++23 
extension}}
+  friend int h(this S); // expected-error {{an explicit object parameter 
cannot appear in a non-member function}} \
+                        // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
+  int h(int x, int (*)(this S)); // expected-error {{an explicit object 
parameter can only appear as the first parameter of a member function}} \
+                                 // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
 
   struct T {
-    int f(this T);
+    int f(this T); // cxx20-warning {{explicit object parameters are a C++23 
extension}}
   };
 
-  friend int T::f(this T);
-  friend int N::A::f(this N::A);
-  friend int N::f(this N::A); // expected-error {{an explicit object parameter 
cannot appear in a non-member function}}
-  int friend func(this T); // expected-error {{an explicit object parameter 
cannot appear in a non-member function}}
+  friend int T::f(this T);       // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+  friend int N::A::f(this N::A); // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+  friend int N::f(this N::A); // expected-error {{an explicit object parameter 
cannot appear in a non-member function}} \
+                              // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+  int friend func(this T); // expected-error {{an explicit object parameter 
cannot appear in a non-member function}} \
+                           // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
 };
 
-using T = int (*)(this int); // expected-error {{an explicit object parameter 
can only appear as the first parameter of a member function}}
-using U = int (S::*)(this int); // expected-error {{an explicit object 
parameter can only appear as the first parameter of a member function}}
-int h(this int); // expected-error {{an explicit object parameter cannot 
appear in a non-member function}}
+using T = int (*)(this int); // expected-error {{an explicit object parameter 
can only appear as the first parameter of a member function}} \
+                             // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
+using U = int (S::*)(this int); // expected-error {{an explicit object 
parameter can only appear as the first parameter of a member function}} \
+                                // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+int h(this int); // expected-error {{an explicit object parameter cannot 
appear in a non-member function}} \
+                 // cxx20-warning {{explicit object parameters are a C++23 
extension}}
 
-int S::f(this S) { return 1; }
+int S::f(this S) { return 1; } // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
 
 namespace a {
 void f();
 };
-void a::f(this auto) {} // expected-error {{an explicit object parameter 
cannot appear in a non-member function}}
+void a::f(this auto) {} // expected-error {{an explicit object parameter 
cannot appear in a non-member function}} \
+                        // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
 }
 
 namespace GH100341 {
 struct X {
     X() = default;
     X(X&&) = default;
-    void operator()(this X);
+    void operator()(this X); // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
 };
 
 void fail() {
     X()();
-    [x = X{}](this auto) {}();
+    [x = X{}](this auto) {}(); // cxx20-warning {{explicit object parameters 
are a C++23 extension}}
 }
 void pass() {
     std::move(X())();
-    std::move([x = X{}](this auto) {})();
+    std::move([x = X{}](this auto) {})(); // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 }
 } // namespace GH100341
 struct R {
-  void f(this auto &&self, int &&r_value_ref) {} // expected-note {{candidate 
function template not viable: expects an rvalue for 2nd argument}}
+  void f(this auto &&self, int &&r_value_ref) {} // expected-note {{candidate 
function template not viable: expects an rvalue for 2nd argument}} \
+                                                 // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
   void g(int &&r_value_ref) {
        f(r_value_ref); // expected-error {{no matching member function for 
call to 'f'}}
   }
@@ -1022,18 +1114,18 @@ struct R {
 
 namespace GH100329 {
 struct A {
-    bool operator == (this const int&, const A&);
+    bool operator == (this const int&, const A&); // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
 };
-bool A::operator == (this const int&, const A&) = default;
+bool A::operator == (this const int&, const A&) = default; // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
 // expected-error@-1 {{invalid parameter type for defaulted equality 
comparison operator; found 'const int &', expected 'const GH100329::A &'}}
 } // namespace GH100329
 
 namespace defaulted_assign {
 struct A {
-  A& operator=(this A, const A&) = default;
+  A& operator=(this A, const A&) = default; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
   // expected-warning@-1 {{explicitly defaulted copy assignment operator is 
implicitly deleted}}
   // expected-note@-2 {{function is implicitly deleted because its declared 
type does not match the type of an implicit copy assignment operator}}
-  A& operator=(this int, const A&) = default;
+  A& operator=(this int, const A&) = default; // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
   // expected-warning@-1 {{explicitly defaulted copy assignment operator is 
implicitly deleted}}
   // expected-note@-2 {{function is implicitly deleted because its declared 
type does not match the type of an implicit copy assignment operator}}
 };
@@ -1041,15 +1133,15 @@ struct A {
 
 namespace defaulted_compare {
 struct A {
-  bool operator==(this A&, const A&) = default;
+  bool operator==(this A&, const A&) = default; // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
   // expected-error@-1 {{defaulted member equality comparison operator must be 
const-qualified}}
-  bool operator==(this const A, const A&) = default;
+  bool operator==(this const A, const A&) = default; // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
   // expected-error@-1 {{invalid parameter type for defaulted equality 
comparison operator; found 'const A', expected 'const defaulted_compare::A &'}}
-  bool operator==(this A, A) = default;
+  bool operator==(this A, A) = default; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 };
 struct B {
   int a;
-  bool operator==(this B, B) = default;
+  bool operator==(this B, B) = default; // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 };
 static_assert(B{0} == B{0});
 static_assert(B{0} != B{1});
@@ -1062,41 +1154,41 @@ static_assert(!__is_same(X<B{0}>, X<B{1}>));
 namespace static_overloaded_operator {
 struct A {
   template<auto N>
-  static void operator()(const char (&)[N]);
-  void operator()(this auto &&, auto &&);
+  static void operator()(const char (&)[N]); // cxx20-warning 2 {{'static' is 
a C++23 extension}}
+  void operator()(this auto &&, auto &&); // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
   void implicit_this() {
-    operator()("123");
+    operator()("123"); // cxx20-note {{requested here}}
   }
 };
 
 struct B {
   template<auto N>
-  void operator()(this auto &&, const char (&)[N]);
-  static void operator()(auto &&);
+  void operator()(this auto &&, const char (&)[N]); // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
+  static void operator()(auto &&);                  // cxx20-warning 2 
{{'static' is a C++23 extension}}
 
   void implicit_this() {
-    operator()("123");
+    operator()("123"); // cxx20-note {{requested here}}
   }
 };
 
 struct C {
   template<auto N>
-  static void operator[](const char (&)[N]);
-  void operator[](this auto &&, auto &&);
+  static void operator[](const char (&)[N]); // cxx20-warning 2 {{'static' is 
a C++23 extension}}
+  void operator[](this auto &&, auto &&);    // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
 
   void implicit_this() {
-    operator[]("123");
+    operator[]("123"); // cxx20-note {{requested here}}
   }
 };
 
 struct D {
   template<auto N>
-  void operator[](this auto &&, const char (&)[N]);
-  static void operator[](auto &&);
+  void operator[](this auto &&, const char (&)[N]); // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
+  static void operator[](auto &&);                  // cxx20-warning 2 
{{'static' is a C++23 extension}}
 
   void implicit_this() {
-    operator[]("123");
+    operator[]("123"); // cxx20-note {{requested here}}
   }
 };
 
@@ -1105,44 +1197,52 @@ struct D {
 namespace GH102025 {
 struct Foo {
   template <class T>
-  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}}
+  constexpr auto operator[](this T &&self, auto... i) // cxx23-note 
{{candidate template ignored: substitution failure [with T = Foo &, i:auto = 
<>]: member '_evaluate' used before its declaration}} \
+                                                      // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
       -> decltype(_evaluate(self, i...)) {
     return self._evaluate(i...);
   }
 
 private:
   template <class T>
-  constexpr auto _evaluate(this T &&self, auto... i) -> decltype((i + ...));
+  constexpr auto _evaluate(this T &&self, auto... i) -> decltype((i + ...)); 
// cxx20-warning {{explicit object parameters are a C++23 extension}}
 };
 
 int main() {
   Foo foo;
-  return foo[]; // expected-error {{no viable overloaded operator[] for type 
'Foo'}}
+  return foo[]; // cxx23-error {{no viable overloaded operator[] for type 
'Foo'}} \
+                // cxx20-error {{expected expression}}
 }
 }
 
 namespace GH100394 {
 struct C1 {
-  void f(this const C1);
+  void f(this const C1); // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
   void f() const;        // ok
 };
 
 struct C2 {
-  void f(this const C2);    // expected-note {{previous declaration is here}}
+  void f(this const C2);    // expected-note {{previous declaration is here}} \
+                            // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
   void f(this volatile C2); // expected-error {{class member cannot be 
redeclared}} \
-                            // expected-warning {{volatile-qualified parameter 
type 'volatile C2' is deprecated}}
+                            // expected-warning {{volatile-qualified parameter 
type 'volatile C2' is deprecated}} \
+                            // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
 };
 
 struct C3 {
   void f(this volatile C3); // expected-note {{previous declaration is here}} \
-                            // expected-warning {{volatile-qualified parameter 
type 'volatile C3' is deprecated}}
-  void f(this const C3);    // expected-error {{class member cannot be 
redeclared}}
+                            // expected-warning {{volatile-qualified parameter 
type 'volatile C3' is deprecated}} \
+                            // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
+  void f(this const C3);    // expected-error {{class member cannot be 
redeclared}} \
+                            // cxx20-warning {{explicit object parameters are 
a C++23 extension}}
 };
 
 struct C4 {
-  void f(this const C4);          // expected-note {{previous declaration is 
here}}
+  void f(this const C4);          // expected-note {{previous declaration is 
here}} \
+                                  // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
   void f(this const volatile C4); // expected-error {{class member cannot be 
redeclared}} \
-                                  // expected-warning {{volatile-qualified 
parameter type 'const volatile C4' is deprecated}}
+                                  // expected-warning {{volatile-qualified 
parameter type 'const volatile C4' is deprecated}} \
+                                  // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 };
 }
 
@@ -1150,10 +1250,10 @@ struct C4 {
 namespace GH112559 {
 struct Wrap  {};
 struct S {
-    constexpr operator Wrap (this const S& self) {
+    constexpr operator Wrap (this const S& self) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
         return Wrap{};
     };
-    constexpr int operator <<(this Wrap self, int i) {
+    constexpr int operator <<(this Wrap self, int i) { // cxx20-warning 
{{explicit object parameters are a C++23 extension}}
         return 0;
     }
 };
@@ -1165,7 +1265,7 @@ static_assert((S{} << 11) == a);
 
 namespace GH135522 {
 struct S {
-  auto f(this auto) -> S;
+  auto f(this auto) -> S;  // cxx20-warning {{explicit object parameters are a 
C++23 extension}}
   bool g() { return f(); } // expected-error {{no viable conversion from 
returned value of type 'S' to function return type 'bool'}}
 };
 }
@@ -1174,28 +1274,28 @@ namespace tpl_address {
 
 struct A {
     template <typename T>
-    void a(this T self); // #tpl-address-a
+    void a(this T self); // #tpl-address-a cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
     template <typename T>
-    void b(this T&& self); // #tpl-address-b
+    void b(this T&& self); // #tpl-address-b cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
     template <typename T>
-    void c(this T self, int); // #tpl-address-c
+    void c(this T self, int); // #tpl-address-c cxx20-warning {{explicit 
object parameters are a C++23 extension}}
 
     template <typename T, typename U>
-    void d(this T self, U); // #tpl-address-d
+    void d(this T self, U); // #tpl-address-d cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
     template <typename T, typename U>
-    requires __is_same_as(U, int)  void e(this T self, U); // #tpl-address-e
+    requires __is_same_as(U, int)  void e(this T self, U); // #tpl-address-e 
cxx20-warning {{explicit object parameters are a C++23 extension}}
 
     template <typename T>
-    requires __is_same_as(T, int)  void f(this T self); // #tpl-address-f
+    requires __is_same_as(T, int)  void f(this T self); // #tpl-address-f 
cxx20-warning {{explicit object parameters are a C++23 extension}}
 
     template <typename T>
-    void g(this T self); // #tpl-address-g1
+    void g(this T self); // #tpl-address-g1 cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 
     template <typename T>
-    void g(this T self, int); // #tpl-address-g2
+    void g(this T self, int); // #tpl-address-g2 cxx20-warning {{explicit 
object parameters are a C++23 extension}}
 
 };
 
@@ -1295,19 +1395,23 @@ void f() {
 namespace GH147121 {
 struct X {};
 struct S1 {
-    bool operator==(this auto &&, const X &); // #S1-cand
+    bool operator==(this auto &&, const X &); // #S1-cand cxx20-warning 
{{explicit object parameters are a C++23 extension}}
 };
 struct S2 {
-    bool operator==(this X, const auto &&); // #S2-cand
+    bool operator==(this X, const auto &&); // #S2-cand cxx20-warning 
{{explicit object parameters are a C++23 extension}}
 };
 
 struct S3 {
-    S3& operator++(this X); // #S3-inc-cand
-    S3& operator++(this int); // #S3-inc-cand
-    int operator[](this X); // #S3-sub-cand
-    int operator[](this int); // #S3-sub-cand2
-    void f(this X); // #S3-f-cand
-    void f(this int); // #S3-f-cand2
+    S3& operator++(this X); // #S3-inc-cand cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    S3& operator++(this int); // #S3-inc-cand cxx20-warning {{explicit object 
parameters are a C++23 extension}}
+    int operator[](this X); // #S3-sub-cand \
+                            // cxx20-warning {{explicit object parameters are 
a C++23 extension}} \
+                            // cxx20-error {{overloaded 'operator[]' cannot 
have no parameter before C++23}}
+    int operator[](this int); // #S3-sub-cand2 \
+                              // cxx20-warning {{explicit object parameters 
are a C++23 extension}} \
+                              // cxx20-error {{overloaded 'operator[]' cannot 
have no parameter before C++23}}
+    void f(this X); // #S3-f-cand cxx20-warning {{explicit object parameters 
are a C++23 extension}}
+    void f(this int); // #S3-f-cand2 cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 };
 
 int main() {
@@ -1337,10 +1441,10 @@ int main() {
     S3 s3;
     ++s3;
     // expected-error@-1{{cannot increment value of type 'S3'}}
-    s3[];
-    // expected-error@-1{{no viable overloaded operator[] for type 'S3'}}
-    // expected-note@#S3-sub-cand {{candidate function not viable: no known 
conversion from 'S3' to 'X' for object argument}}
-    // expected-note@#S3-sub-cand2 {{candidate function not viable: no known 
conversion from 'S3' to 'int' for object argument}}
+    s3[]; // cxx20-error {{expected expression}}
+    // cxx23-error@-1{{no viable overloaded operator[] for type 'S3'}}
+    // cxx23-note@#S3-sub-cand {{candidate function not viable: no known 
conversion from 'S3' to 'X' for object argument}}
+    // cxx23-note@#S3-sub-cand2 {{candidate function not viable: no known 
conversion from 'S3' to 'int' for object argument}}
 
     s3.f();
     // expected-error@-1{{no matching member function for call to 'f'}}
@@ -1351,8 +1455,9 @@ int main() {
 
 namespace GH113185 {
 
-void Bar(this int) { // expected-note {{candidate function}}
-    // expected-error@-1 {{an explicit object parameter cannot appear in a 
non-member function}}
+void Bar(this int) { // expected-note {{candidate function}} \
+                     // cxx20-warning {{explicit object parameters are a C++23 
extension}} \
+                     // expected-error {{an explicit object parameter cannot 
appear in a non-member function}}
     Bar(0);
     Bar(); // expected-error {{no matching function for call to 'Bar'}}
 }
@@ -1393,9 +1498,10 @@ void f() {
 
 namespace GH173943 {
 
-a void Bar(this int) { // expected-note {{candidate function}}
-    // expected-error@-1 {{unknown type name 'a'}}
-    // expected-error@-2 {{an explicit object parameter cannot appear in a 
non-member function}}
+a void Bar(this int) { // expected-note {{candidate function}} \
+                       // cxx20-warning {{explicit object parameters are a 
C++23 extension}} \
+                       // expected-error {{unknown type name 'a'}} \
+                       // expected-error {{an explicit object parameter cannot 
appear in a non-member function}}
     Bar(0);
     Bar(); // expected-error {{no matching function for call to 'Bar'}}
 }
@@ -1404,13 +1510,15 @@ a void Bar(this int) { // expected-note {{candidate 
function}}
 
 namespace ConstexprBacktrace {
   struct S {
-    constexpr int foo(this const S& self, int b) {
+    constexpr int foo(this const S& self, int b) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
       (void)(1/b); // expected-note {{division by zero}}
       return 0;
     }
-    constexpr int foo2(this const S& self) {
+    constexpr int foo2(this const S& self) { // cxx20-warning {{explicit 
object parameters are a C++23 extension}} \
+                                             // cxx20-error {{constexpr 
function never produces a constant expression}}
       (void)(1/0); // expected-note {{division by zero}} \
-                   // expected-warning {{division by zero is undefined}}
+                   // expected-warning {{division by zero is undefined}} \
+                   // cxx20-note {{division by zero}}
       return 0;
     }
   };
@@ -1435,9 +1543,10 @@ namespace ConstexprBacktrace {
 namespace GH176639 {
 
 struct S {
-  void operator()(this S =) // expected-error {{the explicit object parameter 
cannot have a default argument}}
-          // expected-error@-1 {{expected ';' at end of declaration list}}
-          // expected-error@-2 {{expected expression}}
+  void operator()(this S =) // expected-error {{the explicit object parameter 
cannot have a default argument}} \
+                            // cxx20-warning {{explicit object parameters are 
a C++23 extension}} \
+                            // expected-error {{expected ';' at end of 
declaration list}} \
+                            // expected-error {{expected expression}}
 };
 
 void foo() {
@@ -1446,7 +1555,8 @@ void foo() {
 }
 
 struct S2 {
-  void operator()(this S2 = S2 {}){} // expected-error {{the explicit object 
parameter cannot have a default argument}}
+  void operator()(this S2 = S2 {}){} // expected-error {{the explicit object 
parameter cannot have a default argument}} \
+                                     // cxx20-warning {{explicit object 
parameters are a C++23 extension}}
 };
 
 void foo2() {
@@ -1459,7 +1569,7 @@ void foo2() {
 namespace GH177741 {
 
 struct S {
-  static int operator()(this S) { return 0; }
+  static int operator()(this S) { return 0; } // cxx20-warning {{explicit 
object parameters are a C++23 extension}}
   // expected-error@-1 {{an explicit object parameter cannot appear in a 
static function}}
   // expected-note@-2 {{candidate function not viable}}
 };

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to