On Wed, 17 Jun 2026, Marek Polacek wrote:

> On Wed, Jun 17, 2026 at 09:57:18AM -0400, Patrick Palka wrote:
> > 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.
> 
> Updated patch with !TYPE_P, dg.exp=reflect/* passed, ok for trunk/16?
OK
> 
> -- >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.
> 
> The call isn't needed since r17-1271:
> 
>   return convert_nontype_argument (type, convert_from_reference (arg),
>                   complain);
> 
> but we can also avoid calling it on TYPE_P because the function is meant
> for expressions only.
> 
>       PR c++/125764
> 
> gcc/cp/ChangeLog:
> 
>       * reflect.cc (eval_can_substitute): Don't call
>       convert_from_reference on types.
> 
> gcc/testsuite/ChangeLog:
> 
>       * g++.dg/reflect/can_substitute3.C: New test.
> ---
>  gcc/cp/reflect.cc                              |  3 ++-
>  gcc/testsuite/g++.dg/reflect/can_substitute3.C | 10 ++++++++++
>  2 files changed, 12 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 e0b7312c795..8dccf5e99a0 100644
> --- a/gcc/cp/reflect.cc
> +++ b/gcc/cp/reflect.cc
> @@ -5524,7 +5524,8 @@ 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);
> +      if (!TYPE_P (a))
> +     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: d1c12591336de2358c7da4a45855ddac2e02edda
> -- 
> 2.54.0
> 
> 

Reply via email to