On Wed, 10 Jun 2026, Marek Polacek wrote:

> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/16?

OK

> 
> -- >8 --
> Here we ICE because S::S(int) lost its DECL_ARGUMENTS, and so the
> skip_artificial_parms_for in FUNCTION_FIRST_USER_PARM in write_reflection
> crashes on a null tree.   We've thrown away the body of S::S(int) in
> cgraph_node::release_body along with its DECL_ARGUMENTS:
> 
>       if (!keep_arguments)
>         DECL_ARGUMENTS (decl) = NULL;
> 
> This happens in finalize_compilation_unit -> analyze_functions because
> there are no cgraph_node::callers (so referred_to_p() is false I think),
> and .force_output is false.
> 
> We then call mangle_decl from finalize_compilation_unit ->
> dwarf2out_early_finish.
> 
> Instead of FUNCTION_FIRST_USER_PARM we can use DECL_PARM_INDEX, thus
> avoiding the need to either keep the body around or at least set
> keep_arguments.
> 
>       PR c++/125498
> 
> gcc/cp/ChangeLog:
> 
>       * mangle.cc (write_reflection): Use DECL_PARM_INDEX for
>       computing the parameter index.
> 
> gcc/testsuite/ChangeLog:
> 
>       * g++.dg/reflect/mangle7.C: New test.
>       * g++.dg/reflect/parameters_of9.C: New test.
> ---
>  gcc/cp/mangle.cc                              |  9 +--
>  gcc/testsuite/g++.dg/reflect/mangle7.C        | 65 +++++++++++++++++++
>  gcc/testsuite/g++.dg/reflect/parameters_of9.C | 45 +++++++++++++
>  3 files changed, 112 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/reflect/mangle7.C
>  create mode 100644 gcc/testsuite/g++.dg/reflect/parameters_of9.C
> 
> diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
> index 982864ebf0c..a287cded8ae 100644
> --- a/gcc/cp/mangle.cc
> +++ b/gcc/cp/mangle.cc
> @@ -4220,13 +4220,8 @@ write_reflection (tree refl)
>    else if (strcmp (prefix, "pa") == 0)
>      {
>        tree fn = DECL_CONTEXT (arg);
> -      tree args = FUNCTION_FIRST_USER_PARM (fn);
> -      int idx = 0;
> -      while (arg != args)
> -     {
> -       args = DECL_CHAIN (args);
> -       ++idx;
> -     }
> +      /* DECL_PARM_INDEX is 1-based but here we want a 0-based index.  */
> +      const int idx = DECL_PARM_INDEX (arg) - 1;
>        write_compact_number (idx);
>        write_encoding (fn);
>      }
> diff --git a/gcc/testsuite/g++.dg/reflect/mangle7.C 
> b/gcc/testsuite/g++.dg/reflect/mangle7.C
> new file mode 100644
> index 00000000000..f6d9e347204
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/reflect/mangle7.C
> @@ -0,0 +1,65 @@
> +// PR c++/125498
> +// { dg-do compile { target c++26 } }
> +// { dg-additional-options "-freflection" }
> +
> +#include <meta>
> +
> +using namespace std::meta;
> +
> +template<info>
> +void
> +xyzzy ()
> +{
> +}
> +
> +struct S {
> +  void fn1 (const S &)
> +  {
> +    xyzzy<parameters_of (^^S::fn1)[0]> ();
> +  }
> +  void fn2 (this S)
> +  {
> +    xyzzy<parameters_of (^^S::fn2)[0]> ();
> +  }
> +  static void fn3 (int)
> +  {
> +    xyzzy<parameters_of (^^S::fn3)[0]> ();
> +  }
> +};
> +
> +struct V : virtual S {
> +  void fn1 (const V &)
> +  {
> +    xyzzy<parameters_of (^^V::fn1)[0]> ();
> +  }
> +  void fn2 (this V)
> +  {
> +    xyzzy<parameters_of (^^V::fn2)[0]> ();
> +  }
> +  static void fn3 (int)
> +  {
> +    xyzzy<parameters_of (^^V::fn3)[0]> ();
> +  }
> +};
> +
> +void
> +g (int)
> +{
> +  xyzzy<parameters_of (^^g)[0]> ();
> +  S s;
> +  s.fn1 (s);
> +  s.fn2 ();
> +  S::fn3 (42);
> +  V v;
> +  v.fn1 (v);
> +  v.fn2 ();
> +  V::fn3 (42);
> +}
> +
> +// { dg-final { scan-assembler "_Z5xyzzyILDmpa_N1S3fn1ERKS0_EEvv" } }
> +// { dg-final { scan-assembler "_Z5xyzzyILDmpa_NH1S3fn2ES0_EEvv" } }
> +// { dg-final { scan-assembler "_Z5xyzzyILDmpa_N1S3fn3EiEEvv" } }
> +// { dg-final { scan-assembler "_Z5xyzzyILDmpa_N1V3fn1ERKS0_EEvv" } }
> +// { dg-final { scan-assembler "_Z5xyzzyILDmpa_NH1V3fn2ES0_EEvv" } }
> +// { dg-final { scan-assembler "_Z5xyzzyILDmpa_N1V3fn3EiEEvv" } }
> +// { dg-final { scan-assembler "_Z5xyzzyILDmpa_1giEEvv" } }
> diff --git a/gcc/testsuite/g++.dg/reflect/parameters_of9.C 
> b/gcc/testsuite/g++.dg/reflect/parameters_of9.C
> new file mode 100644
> index 00000000000..ef7059a111a
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/reflect/parameters_of9.C
> @@ -0,0 +1,45 @@
> +// PR c++/125498
> +// { dg-do compile { target c++26 } }
> +// { dg-additional-options "-freflection -g" }
> +
> +#include <meta>
> +
> +struct tag {};
> +
> +struct S {
> +  S(int) {}
> +};
> +
> +struct B { };
> +struct A : virtual B { A(int); };
> +
> +template <auto Param> struct GetAnnotations {
> +  static constexpr auto value = std::define_static_array(
> +      std::meta::annotations_of_with_type(Param, ^^tag));
> +};
> +
> +consteval bool test() {
> +  template for (constexpr auto member :
> +             std::define_static_array(std::meta::members_of(
> +                 ^^S, std::meta::access_context::unchecked()))) {
> +    if constexpr (std::meta::is_constructor(member)) {
> +      constexpr auto parameters =
> +       std::define_static_array(std::meta::parameters_of(member));
> +      constexpr auto annotations = GetAnnotations<parameters[0]>::value;
> +      return annotations.empty();
> +    }
> +  }
> +}
> +
> +consteval bool test2() {
> +  template for (constexpr auto member :
> +             std::define_static_array(std::meta::members_of(
> +                 ^^A, std::meta::access_context::unchecked()))) {
> +    if constexpr (std::meta::is_constructor(member)) {
> +      constexpr auto parameters =
> +       std::define_static_array(std::meta::parameters_of(member));
> +      constexpr auto annotations = GetAnnotations<parameters[0]>::value;
> +      return annotations.empty();
> +    }
> +  }
> +}
> 
> base-commit: de7756c90f3bebdf02492842ec355d7e18745e7b
> -- 
> 2.54.0
> 
> 

Reply via email to