On Fri, 12 Jun 2026, Marek Polacek wrote:

> On Fri, Jun 12, 2026 at 10:21:25AM -0400, Patrick Palka wrote:
> > On Fri, 12 Jun 2026, Marek Polacek wrote:
> > 
> > > Tested dg.exp=reflect/* on x86_64-pc-linux-gnu, ok for trunk/16?
> > > 
> > > -- >8 --
> > > Here we crash in convert_from_reference because it gets a FUNCTION_TYPE
> > > int&().  Since its return type is a reference, it passes the c_f_r check:
> > > 
> > >   if (TREE_TYPE (val)
> > >       && TYPE_REF_P (TREE_TYPE (val)))
> > > 
> > > and we crash inside that block.
> > > 
> > > I see no evidence that we need this call at all.  Otherwise we'd have
> > > to guard it with some check before calling it.
> > 
> > Seems the call was added for PR124204 in r16-7744-g195e27c797b695.
> > Why isn't it needed there anymore?
> 
> Since r17-1271 the call to convert_nontype_argument_maybe_dependent
> -> convert_nontype_argument always uses convert_from_reference.
> 
> ...but that means that 16 needs a different fix, maybe just check !TYPE_P
> before the convert_from_reference call in eval_can_substitute.

Gotcha, in that case I'd prefer applying the same fix to both trunk / 16
to simplify future reflection backports (less chance of patch conflicts
etc).  If checking !TYPE_P before convert_from_reference works, it's OK
with me.

> 
> Sorry for not mentioning in the original mail; I'll adjust the description.
> 
> > > 
> > >   PR c++/125764
> > > 
> > > gcc/cp/ChangeLog:
> > > 
> > >   * reflect.cc (eval_can_substitute): Don't call
> > >   convert_from_reference.
> > > 
> > > gcc/testsuite/ChangeLog:
> > > 
> > >   * g++.dg/reflect/can_substitute3.C: New test.
> > > ---
> > >  gcc/cp/reflect.cc                              |  1 -
> > >  gcc/testsuite/g++.dg/reflect/can_substitute3.C | 10 ++++++++++
> > >  2 files changed, 10 insertions(+), 1 deletion(-)
> > >  create mode 100644 gcc/testsuite/g++.dg/reflect/can_substitute3.C
> > > 
> > > diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
> > > index 673b79d0bde..0377639bede 100644
> > > --- a/gcc/cp/reflect.cc
> > > +++ b/gcc/cp/reflect.cc
> > > @@ -5517,7 +5517,6 @@ eval_can_substitute (location_t loc, const 
> > > constexpr_ctx *ctx,
> > >   return throw_exception (loc, ctx,
> > >                           "invalid argument to can_substitute",
> > >                           fun, non_constant_p, jump_target);
> > > -      a = convert_from_reference (a);
> > >        TREE_VEC_ELT (rvec, i) = a;
> > >      }
> > >    if (DECL_TYPE_TEMPLATE_P (r) || DECL_TEMPLATE_TEMPLATE_PARM_P (r))
> > > diff --git a/gcc/testsuite/g++.dg/reflect/can_substitute3.C 
> > > b/gcc/testsuite/g++.dg/reflect/can_substitute3.C
> > > new file mode 100644
> > > index 00000000000..98b8fbb315f
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/reflect/can_substitute3.C
> > > @@ -0,0 +1,10 @@
> > > +// PR c++/125764
> > > +// { dg-do compile { target c++26 } }
> > > +// { dg-additional-options "-freflection" }
> > > +
> > > +#include <meta>
> > > +
> > > +template <typename T>
> > > +struct S {};
> > > +
> > > +static_assert(can_substitute(^^S, {^^int&()}));
> > > 
> > > base-commit: 46f07a7b7d4d5b391723a756e5fb7673800bac57
> > > -- 
> > > 2.54.0
> > > 
> > > 
> > 
> 
> Marek
> 
> 

Reply via email to