On Tue, May 05, 2026 at 09:40:13AM +0200, Jakub Jelinek wrote:
> Hi!
> 
> 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.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/16.2?

Looks good (not an approval).
 
> 2026-05-05  Jakub Jelinek  <[email protected]>
> 
>       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.
> 
> --- gcc/cp/reflect.cc.jj      2026-05-01 21:47:53.656712280 +0200
> +++ gcc/cp/reflect.cc 2026-05-04 16:27:43.017528465 +0200
> @@ -7453,6 +7453,10 @@ extract_ref (location_t loc, const const
>      {
>        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 const
>      {
>        /* 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)))
> --- gcc/testsuite/g++.dg/reflect/extract12.C.jj       2026-05-04 
> 16:29:25.477853239 +0200
> +++ gcc/testsuite/g++.dg/reflect/extract12.C  2026-05-04 16:30:28.990815200 
> +0200
> @@ -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'" }
> 
>       Jakub
> 

Marek

Reply via email to