]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++, libstdc++: Implement CWG1670 and LWG4468
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Nov 2025 10:02:13 +0000 (11:02 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Nov 2025 10:03:07 +0000 (11:03 +0100)
The following patch attempts to implement CWG1670 and related LWG4468.

2025-11-19  Jakub Jelinek  <jakub@redhat.com>

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.

14 files changed:
gcc/cp/parser.cc
gcc/testsuite/g++.dg/DRs/dr1670-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/DRs/dr1670-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/DRs/dr1670-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/auto9.C
gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
gcc/testsuite/g++.dg/cpp1y/auto-fn13.C
gcc/testsuite/g++.dg/cpp1y/auto-fn22.C
gcc/testsuite/g++.dg/cpp1y/auto-fn44.C
gcc/testsuite/g++.dg/cpp1y/auto-fn50.C
gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C
gcc/testsuite/g++.dg/modules/auto-1_a.H
gcc/testsuite/g++.dg/modules/auto-1_b.C
libstdc++-v3/include/std/type_traits

index 06cba31ada671fbe3af07c75816d32ae03308a63..dc26b10f39b9e18d8e5df1d11fe7e6f6ec244462 100644 (file)
@@ -18779,9 +18779,14 @@ cp_parser_conversion_type_id (cp_parser* 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;
diff --git a/gcc/testsuite/g++.dg/DRs/dr1670-1.C b/gcc/testsuite/g++.dg/DRs/dr1670-1.C
new file mode 100644 (file)
index 0000000..1c8430a
--- /dev/null
@@ -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" }
+};
diff --git a/gcc/testsuite/g++.dg/DRs/dr1670-2.C b/gcc/testsuite/g++.dg/DRs/dr1670-2.C
new file mode 100644 (file)
index 0000000..570a04a
--- /dev/null
@@ -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" }
+};
diff --git a/gcc/testsuite/g++.dg/DRs/dr1670-3.C b/gcc/testsuite/g++.dg/DRs/dr1670-3.C
new file mode 100644 (file)
index 0000000..9d13875
--- /dev/null
@@ -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; }
+};
index a3a6caf0a66f47612f5775921605720dce1edb23..2f4de051b0122e323a39e342073d10820b5848e2 100644 (file)
@@ -15,8 +15,8 @@ const std::type_info &t2 = typeid (auto *);   // { dg-error "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
index 98885799de989ce1d1fa5f158afeeb9205451100..1ee1755bd00502036a9e0f830d77928c34aa82ec 100644 (file)
@@ -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 {
index 96b4b0c64aadd45a45e57270fe5bfd26a23a0967..bb4f3ca94ee91bf718bbe64dce14d741675433f8 100644 (file)
@@ -1,4 +1,5 @@
 // { dg-do compile { target c++14 } }
+// { dg-options "" }
 
 struct A {
   template <class T>
index b16a7644c0f8146b4b9f61e7b7504e8c5c11c212..68d8d853b3c398bc0b989ad0613802843263b9b8 100644 (file)
@@ -1,4 +1,5 @@
 // { dg-do compile { target c++14 } }
+// { dg-options "" }
 
 struct A
 {
index e35215d64c7ea1409913185abd505c6ed775b438..4439f47abf5409f40df32b77bf627b792da921f1 100644 (file)
@@ -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);
index a2c7e40755b044fcf2f9daadb256770f349c20df..8a9010521ad8dd4c07b48c660978f56af181dbb2 100644 (file)
@@ -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;
   }
index def05f5fb256d15beb29243dd6e81197273b8f83..58f9a3113510f318881af0ea049f012c482b7517 100644 (file)
@@ -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>
 
index 4d3bc77dbb1de2f6a41f7ada562e773f206b2067..e9cbd00aceb7239f4c2ab5de4d6c9ac6441ba39f 100644 (file)
@@ -1,4 +1,4 @@
-// { dg-additional-options -fmodule-header }
+// { dg-options -fmodule-header }
 // { dg-module-cmi {} }
 
 #include "auto-1.h"
index 96350662fed42d48402a58889aa897590f8f3f84..f6422339ae5611e649a2499810b1dc209e05d5c5 100644 (file)
@@ -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";
index d28b077398bef31bbd5d29491797f948bf274932..5c09fac86629e29399ff13d57cd058959307a8f3 100644 (file)
@@ -4682,7 +4682,7 @@ template<typename _Ret, typename _Fn, typename... _Args>
       }
 
     constexpr
-    operator decltype(auto)() const noexcept
+    operator decltype(value)() const noexcept
     { return value; }
   };