Re: [PATCH] c++: Mangling fix for type alias reflections [PR125680]

Jason Merrill <[email protected]> Wed, 5 Aug 2026 22:13:34 -0400
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
On 6/11/26 4:21 AM, Jakub Jelinek wrote:
> Hi!
> 
> The following testcase ICEs, because we use write_unqualified_name to
> write the type alias name.  Unfortunately, it is an alias for an unnamed
> type and write_unqualified_name in that case uses
>        if (TREE_CODE (decl) == TYPE_DECL
>            && enum_with_enumerator_for_linkage_p (type))
>          write_unnamed_enum_name (type);
>        else if (TREE_CODE (decl) == TYPE_DECL && TYPE_UNNAMED_P (type))
>          write_unnamed_type_name (type);
>        else if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (type))
>          write_closure_type_name (type);
>        else
>          write_source_name (DECL_NAME (decl));
> and write_unnamed_type_node
>    else if (TYPE_CLASS_SCOPE_P (type))
>      discriminator = nested_anon_class_index (type);
> and nested_anon_class_index ICEs, because type is the type alias and
> obviously it can't find a type alias among DECL_IMPLICIT_TYPEDEF_P nembers.
> In this case, we really want to write the source name of the type alias
> (which always should have DECL_NAME), regardless of what the dealias
> of the type alias is (that is emitted later in the mangling).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.
> Note, this isn't the only PR against this area, there is another one where
> write_prefix (decl_mangling_context (arg)); doesn't work properly for
> local names.
> 
> 2026-06-11  Jakub Jelinek  <[email protected]>
> 
> 	PR c++/125680
> 	* mangle.cc (write_reflection): For type aliases use maybe_write_module
> 	and write_source_name instead of write_unqualified_name.
> 
> 	* g++.dg/reflect/mangle8.C: New test.
> 
> --- gcc/cp/mangle.cc.jj	2026-05-30 17:45:09.368109989 +0200
> +++ gcc/cp/mangle.cc	2026-06-10 10:59:34.208208674 +0200
> @@ -4245,7 +4245,9 @@ write_reflection (tree refl)
>   	 write_template_args, it shouldn't be
>   	 remembered among substitutions.  */
>         write_prefix (decl_mangling_context (arg));
> -      write_unqualified_name (arg);
> +      if (modules_p ())
> +	maybe_write_module (arg);
> +      write_source_name (DECL_NAME (arg));
>         tree template_info = maybe_template_info (arg);
>         if (template_info)
>   	write_template_args (TI_ARGS (template_info));
> --- gcc/testsuite/g++.dg/reflect/mangle8.C.jj	2026-06-10 11:16:23.143869147 +0200
> +++ gcc/testsuite/g++.dg/reflect/mangle8.C	2026-06-10 11:19:50.389129484 +0200
> @@ -0,0 +1,32 @@
> +// PR c++/125680
> +// { dg-do compile { target c++26 } }
> +// { dg-additional-options "-freflection" }
> +
> +#include <meta>
> +
> +struct A { struct { int b; } a[4]; };
> +
> +template <std::meta::info I>
> +struct B
> +{
> +  consteval static std::meta::info
> +  foo ()
> +  {
> +    if constexpr (is_array_type (I))
> +      {
> +	using C = typename [: remove_extent (I) :];
> +	return ^^C;
> +      }
> +    else
> +      {
> +        constexpr auto c = type_of (nonstatic_data_members_of (I, std::meta::access_context::current ())[0]);
> +        using C = typename [: c :];
> +        return ^^C;
> +      }
> +  }
> +  constexpr static std::meta::info b = foo ();
> +};
> +
> +constexpr auto a = B <^^A>::b;
> +constexpr auto b = B <a>::b;
> +constexpr auto c = B <b>::b;
> 
> 	Jakub
>