See <https://wg21.link/p1169>.
Created attachment 53565 [details] gcc13-pr106651-wip.patch WIP patch which has parts of the changes implemented. What is missing is [over.match.best.general]/1 and [over.best.ics.general] changes and the library side, which means e.g. for the testcase from the paper: struct less { static constexpr auto operator()(int i, int j) -> bool { return i < j; } using P = bool(*)(int, int); operator P() const { return operator(); } }; static_assert(less{}(1, 2)); we ICE. Testcase I've been playing with that compiles now: template <typename T> struct S { static constexpr bool operator() (T const& x, T const& y) { return x < y; }; }; template <typename T> void bar (T &x) { x (1, 2); } void foo () { auto a = [](int x, int y) static { return x + y; }; bar (*a); auto b = []<typename T, typename U>(T x, U y) static { return x + y; }; b (1, 2L); S<int> s; s(1, 2); }
Created attachment 53571 [details] gcc13-pr106651.patch Full untested patch.
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:303976a6076f2839354702fd2caa049fa7cbbdc2 commit r13-2892-g303976a6076f2839354702fd2caa049fa7cbbdc2 Author: Jakub Jelinek <jakub@redhat.com> Date: Tue Sep 27 08:36:28 2022 +0200 c++: Implement C++23 P1169R4 - static operator() [PR106651] The following patch attempts to implement C++23 P1169R4 - static operator() paper's compiler side (there is some small library side too not implemented yet). This allows static members as user operator() declarations and static specifier on lambdas without lambda capture. The synthetized conversion operator changes for static lambdas as it can just return the operator() static method address, doesn't need to create a thunk for it. The change in call.cc (joust) is to avoid ICEs because we assumed that len could be different only if both candidates are direct calls but it can be one direct and one indirect call, and to implement the [over.match.best.general]/1 and [over.best.ics.general] changes from the paper (implemented always as Jason is sure it doesn't make a difference in C++20 and earlier unless static member function operator() or static lambda which we accept with pedwarn in earlier standards too appears and my testing confirmed that). 2022-09-27 Jakub Jelinek <jakub@redhat.com> PR c++/106651 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Predefine __cpp_static_call_operator=202207L for C++23. gcc/cp/ * cp-tree.h (LAMBDA_EXPR_STATIC_P): Implement C++23 P1169R4 - static operator(). Define. * parser.cc (CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR): Document that it also allows static. (cp_parser_lambda_declarator_opt): Handle static lambda specifier. (cp_parser_decl_specifier_seq): Allow RID_STATIC for CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR. * decl.cc (grok_op_properties): If operator() isn't a method, use a different error wording, if it is static member function, allow it (for C++20 and older with a pedwarn unless it is a lambda function or template instantiation). * call.cc (joust): Don't ICE if one candidate is static member function and the other is an indirect call. If the parameter conversion on the other candidate is user defined conversion, ellipsis or bad conversion, make static member function candidate a winner for that parameter. * lambda.cc (maybe_add_lambda_conv_op): Handle static lambdas. * error.cc (dump_lambda_function): Print static for static lambdas. gcc/testsuite/ * g++.dg/template/error30.C: Adjust expected diagnostics. * g++.dg/cpp1z/constexpr-lambda13.C: Likewise. * g++.dg/cpp23/feat-cxx2b.C: Test __cpp_static_call_operator. * g++.dg/cpp23/static-operator-call1.C: New test. * g++.dg/cpp23/static-operator-call2.C: New test. * g++.old-deja/g++.jason/operator.C: Adjust expected diagnostics.
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:614e5696d730a65998ff5b0373f905795a758dd6 commit r13-2897-g614e5696d730a65998ff5b0373f905795a758dd6 Author: Jonathan Wakely <jwakely@redhat.com> Date: Tue Sep 27 11:25:51 2022 +0100 libstdc++: Adjust deduction guides for static operator() [PR106651] Adjust the deduction guides for std::function and std::packaged_task to work with static call operators. This finishes the implementation of P1169R4 for C++23. libstdc++-v3/ChangeLog: PR c++/106651 * include/bits/std_function.h (__function_guide_t): New alias template. [__cpp_static_call_operator] (__function_guide_static_helper): New class template. (function): Use __function_guide_t in deduction guide. * include/std/future (packaged_task): Use __function_guide_t in deduction guide. * testsuite/20_util/function/cons/deduction_c++23.cc: New test. * testsuite/30_threads/packaged_task/cons/deduction_c++23.cc: New test.
This is complete now.
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:4f181f9c7ee3efc509d185fdfda33be9018f1611 commit r13-6533-g4f181f9c7ee3efc509d185fdfda33be9018f1611 Author: Jason Merrill <jason@redhat.com> Date: Mon Mar 6 21:36:28 2023 -0500 c++: static lambda tsubst [PR108526] A missed piece of the patch for static operator(): in tsubst_function_decl, we don't want to replace the first parameter with a new closure pointer if operator() is static. PR c++/108526 PR c++/106651 gcc/cp/ChangeLog: * pt.cc (tsubst_function_decl): Don't replace the closure parameter if DECL_STATIC_FUNCTION_P. gcc/testsuite/ChangeLog: * g++.dg/cpp23/static-operator-call5.C: Pass -g.