[gcc r16-5412] c++, libstdc++: Implement CWG1670 and LWG4468
Jakub Jelinek
jakub@gcc.gnu.org
Wed Nov 19 10:03:59 GMT 2025
https://gcc.gnu.org/g:3d000da53203c9f17b29dd9328d12dfcbe8d03aa
commit r16-5412-g3d000da53203c9f17b29dd9328d12dfcbe8d03aa
Author: Jakub Jelinek <jakub@redhat.com>
Date: Wed Nov 19 11:02:13 2025 +0100
c++, libstdc++: Implement CWG1670 and LWG4468
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.
Diff:
---
gcc/cp/parser.cc | 11 ++++++++---
gcc/testsuite/g++.dg/DRs/dr1670-1.C | 9 +++++++++
gcc/testsuite/g++.dg/DRs/dr1670-2.C | 10 ++++++++++
gcc/testsuite/g++.dg/DRs/dr1670-3.C | 10 ++++++++++
gcc/testsuite/g++.dg/cpp0x/auto9.C | 4 ++--
gcc/testsuite/g++.dg/cpp1y/auto-fn12.C | 2 +-
gcc/testsuite/g++.dg/cpp1y/auto-fn13.C | 1 +
gcc/testsuite/g++.dg/cpp1y/auto-fn22.C | 1 +
gcc/testsuite/g++.dg/cpp1y/auto-fn44.C | 5 +++--
gcc/testsuite/g++.dg/cpp1y/auto-fn50.C | 3 ++-
gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C | 1 +
gcc/testsuite/g++.dg/modules/auto-1_a.H | 2 +-
gcc/testsuite/g++.dg/modules/auto-1_b.C | 2 +-
libstdc++-v3/include/std/type_traits | 2 +-
14 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 06cba31ada67..dc26b10f39b9 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -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
index 000000000000..1c8430a6558b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr1670-1.C
@@ -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
index 000000000000..570a04ad796d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr1670-2.C
@@ -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
index 000000000000..9d1387572298
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr1670-3.C
@@ -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; }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto9.C b/gcc/testsuite/g++.dg/cpp0x/auto9.C
index a3a6caf0a66f..2f4de051b012 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto9.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto9.C
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
index 98885799de98..1ee1755bd005 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
@@ -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 {
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn13.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn13.C
index 96b4b0c64aad..bb4f3ca94ee9 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn13.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn13.C
@@ -1,4 +1,5 @@
// { dg-do compile { target c++14 } }
+// { dg-options "" }
struct A {
template <class T>
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C
index b16a7644c0f8..68d8d853b3c3 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C
@@ -1,4 +1,5 @@
// { dg-do compile { target c++14 } }
+// { dg-options "" }
struct A
{
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn44.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn44.C
index e35215d64c7e..4439f47abf54 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn44.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn44.C
@@ -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);
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn50.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn50.C
index a2c7e40755b0..8a9010521ad8 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn50.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn50.C
@@ -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;
}
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C
index def05f5fb256..58f9a3113510 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C
@@ -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>
diff --git a/gcc/testsuite/g++.dg/modules/auto-1_a.H b/gcc/testsuite/g++.dg/modules/auto-1_a.H
index 4d3bc77dbb1d..e9cbd00aceb7 100644
--- a/gcc/testsuite/g++.dg/modules/auto-1_a.H
+++ b/gcc/testsuite/g++.dg/modules/auto-1_a.H
@@ -1,4 +1,4 @@
-// { dg-additional-options -fmodule-header }
+// { dg-options -fmodule-header }
// { dg-module-cmi {} }
#include "auto-1.h"
diff --git a/gcc/testsuite/g++.dg/modules/auto-1_b.C b/gcc/testsuite/g++.dg/modules/auto-1_b.C
index 96350662fed4..f6422339ae56 100644
--- a/gcc/testsuite/g++.dg/modules/auto-1_b.C
+++ b/gcc/testsuite/g++.dg/modules/auto-1_b.C
@@ -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";
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index d28b077398be..5c09fac86629 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -4682,7 +4682,7 @@ template<typename _Ret, typename _Fn, typename... _Args>
}
constexpr
- operator decltype(auto)() const noexcept
+ operator decltype(value)() const noexcept
{ return value; }
};
More information about the Libstdc++-cvs
mailing list