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
