[gcc r17-374] c++: Fix up extract_ref [PR125111]

Jakub Jelinek jakub@gcc.gnu.org
Thu May 7 06:55:04 GMT 2026


https://gcc.gnu.org/g:ef48b322cd98e23de57ad0d8f09ec02aa97d40c4

commit r17-374-gef48b322cd98e23de57ad0d8f09ec02aa97d40c4
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu May 7 08:54:21 2026 +0200

    c++: Fix up extract_ref [PR125111]
    
    https://eel.is/c++draft/meta.reflection.extract#5.2 requests that
    is_convertible_v<remove_reference_t<U>(*)[], remove_reference_t<T>(*)[]>
    is tested and if it not true, the function throws.
    If U/T are references to function/method/array[], we try to build
    array of types which are not valid in arrays and ICE shortly after that.
    The following patch makes sure we don't create arrays in that case
    and instead just throw the exception.  We can't have references to void
    or references to references, so I think the other problematic cases
    of creating arrays can't trigger.
    
    2026-05-07  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/125111
            * reflect.cc (extract_ref): Throw instead of trying to build
            arrays of functions, methods or arrays with NULL TYPE_DOMAIN.
    
            * g++.dg/reflect/extract12.C: New test.
    
    Reviewed-by: Jason Merrill <jason@redhat.com>

Diff:
---
 gcc/cp/reflect.cc                        | 10 +++++++++-
 gcc/testsuite/g++.dg/reflect/extract12.C | 14 ++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 816950d43ede..bcbb5980c9f3 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -7453,6 +7453,10 @@ extract_ref (location_t loc, const constexpr_ctx *ctx, tree T, tree r,
     {
       if (TYPE_REF_P (type))
 	type = TREE_TYPE (type);
+      if (FUNC_OR_METHOD_TYPE_P (type)
+	  || (TREE_CODE (type) == ARRAY_TYPE
+	      && TYPE_DOMAIN (type) == NULL_TREE))
+	return error_mark_node;
       type = build_cplus_array_type (type, NULL_TREE);
       return build_pointer_type (type);
     };
@@ -7462,7 +7466,11 @@ extract_ref (location_t loc, const constexpr_ctx *ctx, tree T, tree r,
     {
       /* The wording is saying that U is the type of r.  */
       tree U = TREE_TYPE (r);
-      if (is_convertible (adjust_type (U), adjust_type (T))
+      tree adju = adjust_type (U);
+      tree adjt = adjust_type (T);
+      if (adju != error_mark_node
+	  && adjt != error_mark_node
+	  && is_convertible (adju, adjt)
 	  && (!var_p || is_constant_expression (r)))
 	{
 	  if (TYPE_REF_P (TREE_TYPE (r)))
diff --git a/gcc/testsuite/g++.dg/reflect/extract12.C b/gcc/testsuite/g++.dg/reflect/extract12.C
new file mode 100644
index 000000000000..cc5c856e754b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/extract12.C
@@ -0,0 +1,14 @@
+// PR c++/125111
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+using A = void ();
+extern A &a;
+constexpr auto b = ^^a;
+constexpr auto c = std::meta::extract <A &> (b);	// { dg-error "uncaught exception of type 'std::meta::exception'; 'what\\\(\\\)': 'value cannot be extracted'" }
+using B = int [];
+extern B &d;
+constexpr auto e = ^^d;
+constexpr auto f = std::meta::extract <B &> (e);	// { dg-error "uncaught exception of type 'std::meta::exception'; 'what\\\(\\\)': 'value cannot be extracted'" }


More information about the Gcc-cvs mailing list