Hi! Working virtually out of Baker Island.
The following patch attempts to implement CWG1670. Tested on x86_64-linux, ok for trunk? 2025-11-17 Jakub Jelinek <[email protected]> gcc/cp/ * parser.cc (cp_parser_conversion_type_id): Implement C++ DR1670 - auto as conversion-type-id. Pedwarn on conversion operators with placeholder return type. gcc/testsuite/ * g++.dg/DRs/dr1670-1.C: New test. * g++.dg/DRs/dr1670-2.C: New test. * g++.dg/DRs/dr1670-3.C: New test. * g++.dg/modules/auto-1_a.H: Use dg-options instead of dg-additional-options. * g++.dg/modules/auto-1_b.C: Likewise. * g++.dg/cpp1y/auto-fn12.C: Likewise. * g++.dg/cpp1y/auto-fn13.C: Add empty dg-options. * g++.dg/cpp1y/auto-fn22.C: Likewise. * g++.dg/cpp1y/constexpr-assert2.C: Likewise. * g++.dg/cpp1y/auto-fn44.C: Add dg-options -Wpedantic and expect further warnings. * g++.dg/cpp1y/auto-fn50.C: Likewise. * g++.dg/cpp0x/auto9.C: Expect two errors always rather than just for C++11. libstdc++-v3/ * include/std/type_traits (constant_wrapper conversion operator): Use decltype(value) instead of decltype(auto). Resolves LWG4468. --- gcc/cp/parser.cc.jj 2025-11-15 16:03:45.587512374 +0100 +++ gcc/cp/parser.cc 2025-11-17 10:21:57.667975827 +0100 @@ -18779,9 +18779,14 @@ cp_parser_conversion_type_id (cp_parser* error ("invalid use of %<auto%> in conversion operator"); return error_mark_node; } - else if (template_parm_scope_p ()) - warning (0, "use of %<auto%> in member template " - "conversion operator can never be deduced"); + else + { + pedwarn (input_location, OPT_Wpedantic, + "invalid use of %<auto%> in conversion operator"); + if (template_parm_scope_p ()) + warning (0, "use of %<auto%> in member template " + "conversion operator can never be deduced"); + } } return type_specified; --- gcc/testsuite/g++.dg/DRs/dr1670-1.C.jj 2025-11-17 10:27:56.930906572 +0100 +++ gcc/testsuite/g++.dg/DRs/dr1670-1.C 2025-11-17 10:27:07.271607272 +0100 @@ -0,0 +1,9 @@ +// DR 1670 - auto as conversion-type-id +// { dg-do compile { target c++14 } } + +struct S { + operator auto () { return 0; } // { dg-error "invalid use of 'auto' in conversion operator" } +}; +struct T { + operator decltype (auto) () { return 0; } // { dg-error "invalid use of 'auto' in conversion operator" } +}; --- gcc/testsuite/g++.dg/DRs/dr1670-2.C.jj 2025-11-17 10:27:59.807865977 +0100 +++ gcc/testsuite/g++.dg/DRs/dr1670-2.C 2025-11-17 10:27:39.339154793 +0100 @@ -0,0 +1,10 @@ +// DR 1670 - auto as conversion-type-id +// { dg-do compile { target c++14 } } +// { dg-options "-Wpedantic" } + +struct S { + operator auto () { return 0; } // { dg-warning "invalid use of 'auto' in conversion operator" } +}; +struct T { + operator decltype (auto) () { return 0; } // { dg-warning "invalid use of 'auto' in conversion operator" } +}; --- gcc/testsuite/g++.dg/DRs/dr1670-3.C.jj 2025-11-17 10:28:02.743824551 +0100 +++ gcc/testsuite/g++.dg/DRs/dr1670-3.C 2025-11-17 10:28:28.672458692 +0100 @@ -0,0 +1,10 @@ +// DR 1670 - auto as conversion-type-id +// { dg-do compile { target c++14 } } +// { dg-options "" } + +struct S { + operator auto () { return 0; } +}; +struct T { + operator decltype (auto) () { return 0; } +}; --- gcc/testsuite/g++.dg/modules/auto-1_a.H.jj 2020-12-23 14:09:58.845107420 +0100 +++ gcc/testsuite/g++.dg/modules/auto-1_a.H 2025-11-17 12:56:11.193418523 +0100 @@ -1,4 +1,4 @@ -// { dg-additional-options -fmodule-header } +// { dg-options -fmodule-header } // { dg-module-cmi {} } #include "auto-1.h" --- gcc/testsuite/g++.dg/modules/auto-1_b.C.jj 2020-12-23 14:09:58.845107420 +0100 +++ gcc/testsuite/g++.dg/modules/auto-1_b.C 2025-11-17 12:56:04.923503501 +0100 @@ -1,4 +1,4 @@ -// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } +// { dg-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } #include "auto-1.h" import "auto-1_a.H"; --- gcc/testsuite/g++.dg/cpp1y/auto-fn13.C.jj 2020-01-12 11:54:37.111402878 +0100 +++ gcc/testsuite/g++.dg/cpp1y/auto-fn13.C 2025-11-17 12:50:00.356444605 +0100 @@ -1,4 +1,5 @@ // { dg-do compile { target c++14 } } +// { dg-options "" } struct A { template <class T> --- gcc/testsuite/g++.dg/cpp1y/auto-fn22.C.jj 2020-01-12 11:54:37.112402863 +0100 +++ gcc/testsuite/g++.dg/cpp1y/auto-fn22.C 2025-11-17 12:53:30.097601910 +0100 @@ -1,4 +1,5 @@ // { dg-do compile { target c++14 } } +// { dg-options "" } struct A { --- gcc/testsuite/g++.dg/cpp1y/auto-fn44.C.jj 2020-01-12 11:54:37.112402863 +0100 +++ gcc/testsuite/g++.dg/cpp1y/auto-fn44.C 2025-11-17 12:52:04.928756234 +0100 @@ -1,11 +1,12 @@ // PR c++/79474 // { dg-do compile { target c++14 } } +// { dg-options "-Wpedantic" } struct Funject { - operator auto() { return +[](bool b) {return b;}; } + operator auto() { return +[](bool b) {return b;}; } // { dg-warning "invalid use of 'auto' in conversion operator" } operator auto() { return +[](bool b, bool, bool) {return b;}; } // { dg-error "cannot be overloaded" } -}; +}; // { dg-warning "invalid use of 'auto' in conversion operator" "" { target *-*-* } .-1 } Funject fun; auto bbb = fun(true); --- gcc/testsuite/g++.dg/cpp1y/auto-fn50.C.jj 2020-01-12 11:54:37.112402863 +0100 +++ gcc/testsuite/g++.dg/cpp1y/auto-fn50.C 2025-11-17 12:52:56.611055766 +0100 @@ -1,10 +1,11 @@ // PR c++/84906 // { dg-do compile { target c++14 } } +// { dg-options "-Wpedantic" } extern "C" int puts(const char*); struct aa { - operator auto() { + operator auto() { // { dg-warning "invalid use of 'auto' in conversion operator" } puts("auto"); return false; } --- gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C.jj 2025-04-08 14:09:01.101144742 +0200 +++ gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C 2025-11-17 12:54:05.047128227 +0100 @@ -1,6 +1,7 @@ // PR c++/65985 // { dg-do compile { target c++14 } } // { dg-skip-if "requires hosted libstdc++ for cassert" { ! hostedlib } } +// { dg-options "" } #include <cassert> --- gcc/testsuite/g++.dg/cpp1y/auto-fn12.C.jj 2021-12-30 15:12:43.259149926 +0100 +++ gcc/testsuite/g++.dg/cpp1y/auto-fn12.C 2025-11-17 12:49:35.183785778 +0100 @@ -1,6 +1,6 @@ // { dg-do compile { target c++14 } } // { dg-final { scan-assembler "_ZN1AIiEcvDaEv" } } -// { dg-additional-options -fno-implicit-constexpr } +// { dg-options -fno-implicit-constexpr } template <class T> struct A { --- gcc/testsuite/g++.dg/cpp0x/auto9.C.jj 2021-12-30 15:12:43.254149996 +0100 +++ gcc/testsuite/g++.dg/cpp0x/auto9.C 2025-11-17 12:54:54.240461493 +0100 @@ -15,8 +15,8 @@ const std::type_info &t2 = typeid (auto struct A { - operator auto (); // { dg-error "auto" "" { target { ! c++14 } } } - operator auto *(); // { dg-error "auto" "" { target { ! c++14 } } } + operator auto (); // { dg-error "auto" } + operator auto *(); // { dg-error "auto" } }; struct A2 --- libstdc++-v3/include/std/type_traits.jj 2025-11-08 14:44:20.631433760 +0100 +++ libstdc++-v3/include/std/type_traits 2025-11-17 12:27:26.833970359 +0100 @@ -4682,7 +4682,7 @@ template<typename _Ret, typename _Fn, ty } constexpr - operator decltype(auto)() const noexcept + operator decltype(value)() const noexcept { return value; } }; Jakub
