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

Reply via email to