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
