On Mon, 17 Nov 2025 at 12:01, Jakub Jelinek <[email protected]> wrote: > > Hi! > > Working virtually out of Baker Island.
/me waves from a nearby island ;-) > > The following patch attempts to implement CWG1670. > > Tested on x86_64-linux, ok for trunk? The libstdc++ part is OK of course, thanks. > > 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 >
