On Sat, Mar 07, 2026 at 10:21:34AM +0100, Jakub Jelinek wrote:
> Hi!
>
> {,u8}display_string_of was printing any unnamed FIELD_DECL as
> %T::<unnamed bit-field>, but anon union member is also unnamed and
> is not a bit-field.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
Looks fine to me.
> 2026-03-07 Jakub Jelinek <[email protected]>
>
> PR c++/124388
> * reflect.cc (eval_display_string_of): Only print <unnmamed bit-field>
> for DECL_UNNAMED_BIT_FIELD, otherwise print <unnamed member>.
>
> * g++.dg/reflect/display_string_of1.C (S, NS5::S): Add
> union { int a; }. Add static_assertions that the unnamed non-static
> data member is printed as <unnamed member>.
> * g++.dg/reflect/u8display_string_of1.C (S, NS5::S): Add
> union { int a; }. Add static_assertions that the unnamed non-static
> data member is printed as <unnamed member>.
>
> --- gcc/cp/reflect.cc.jj 2026-03-05 09:19:22.173774816 +0100
> +++ gcc/cp/reflect.cc 2026-03-06 11:52:58.021949635 +0100
> @@ -3604,7 +3604,12 @@ eval_display_string_of (location_t loc,
> else if (DECL_P (r) && (DECL_NAME (r) || TREE_CODE (r) == NAMESPACE_DECL))
> pp_printf (&pp, "%D", r);
> else if (TREE_CODE (r) == FIELD_DECL)
> - pp_printf (&pp, "%T::<unnamed bit-field>", DECL_CONTEXT (r));
> + {
> + if (DECL_UNNAMED_BIT_FIELD (r))
> + pp_printf (&pp, "%T::<unnamed bit-field>", DECL_CONTEXT (r));
> + else
> + pp_printf (&pp, "%T::<unnamed member>", DECL_CONTEXT (r));
> + }
> else if (kind == REFLECT_BASE)
> {
> tree d = direct_base_derived (r);
> --- gcc/testsuite/g++.dg/reflect/display_string_of1.C.jj 2026-01-15
> 16:33:47.007097959 +0100
> +++ gcc/testsuite/g++.dg/reflect/display_string_of1.C 2026-03-06
> 11:51:46.572128144 +0100
> @@ -17,6 +17,7 @@ struct B {};
> struct S : B {
> int mem;
> int : 0;
> + union { int a; };
> };
> struct T {
> T () {}
> @@ -106,6 +107,7 @@ foo (int a, const long b, T c, int d[4],
> static_assert (display_string_of (^^S) == "S");
> static_assert (display_string_of (^^S::mem) == "S::mem");
> static_assert (display_string_of (members_of (^^S, ctx)[1]) ==
> "S::<unnamed bit-field>");
> + static_assert (display_string_of (nonstatic_data_members_of (^^S, ctx)[1])
> == "S::<unnamed member>");
> static_assert (display_string_of (^^TCls) == "template<auto <anonymous> >
> struct TCls");
> static_assert (display_string_of (^^TFn) == "template<auto <anonymous> >
> void TFn()");
> static_assert (display_string_of (^^TVar) == "template<auto <anonymous> >
> int TVar<<anonymous> >");
> @@ -145,6 +147,7 @@ namespace NS5 {
> struct S : B {
> int mem;
> int : 0;
> + union { int a; };
> };
> struct T {
> T () {}
> @@ -212,6 +215,7 @@ namespace NS5 {
> static_assert (display_string_of (^^S) == "NS5::S");
> static_assert (display_string_of (^^S::mem) == "NS5::S::mem");
> static_assert (display_string_of (members_of (^^S, ctx)[1]) ==
> "NS5::S::<unnamed bit-field>");
> + static_assert (display_string_of (nonstatic_data_members_of (^^S,
> ctx)[1]) == "NS5::S::<unnamed member>");
> static_assert (display_string_of (^^TCls) == "template<auto <anonymous>
> > struct NS5::TCls");
> static_assert (display_string_of (^^TFn) == "template<auto <anonymous> >
> void NS5::TFn()");
> static_assert (display_string_of (^^TVar) == "template<auto <anonymous>
> > int NS5::TVar<<anonymous> >");
> --- gcc/testsuite/g++.dg/reflect/u8display_string_of1.C.jj 2026-01-15
> 16:33:47.017097789 +0100
> +++ gcc/testsuite/g++.dg/reflect/u8display_string_of1.C 2026-03-06
> 11:37:31.895312350 +0100
> @@ -17,6 +17,7 @@ struct B {};
> struct S : B {
> int mem;
> int : 0;
> + union { int a; };
> };
> struct T {
> T () {}
> @@ -106,6 +107,7 @@ foo (int a, const long b, T c, int d[4],
> static_assert (u8display_string_of (^^S) == u8"S");
> static_assert (u8display_string_of (^^S::mem) == u8"S::mem");
> static_assert (u8display_string_of (members_of (^^S, ctx)[1]) ==
> u8"S::<unnamed bit-field>");
> + static_assert (u8display_string_of (nonstatic_data_members_of (^^S,
> ctx)[1]) == u8"S::<unnamed member>");
> static_assert (u8display_string_of (^^TCls) == u8"template<auto
> <anonymous> > struct TCls");
> static_assert (u8display_string_of (^^TFn) == u8"template<auto <anonymous>
> > void TFn()");
> static_assert (u8display_string_of (^^TVar) == u8"template<auto
> <anonymous> > int TVar<<anonymous> >");
> @@ -145,6 +147,7 @@ namespace NS5 {
> struct S : B {
> int mem;
> int : 0;
> + union { int a; };
> };
> struct T {
> T () {}
> @@ -212,6 +215,7 @@ namespace NS5 {
> static_assert (u8display_string_of (^^S) == u8"NS5::S");
> static_assert (u8display_string_of (^^S::mem) == u8"NS5::S::mem");
> static_assert (u8display_string_of (members_of (^^S, ctx)[1]) ==
> u8"NS5::S::<unnamed bit-field>");
> + static_assert (u8display_string_of (nonstatic_data_members_of (^^S,
> ctx)[1]) == u8"NS5::S::<unnamed member>");
> static_assert (u8display_string_of (^^TCls) == u8"template<auto
> <anonymous> > struct NS5::TCls");
> static_assert (u8display_string_of (^^TFn) == u8"template<auto
> <anonymous> > void NS5::TFn()");
> static_assert (u8display_string_of (^^TVar) == u8"template<auto
> <anonymous> > int NS5::TVar<<anonymous> >");
>
> Jakub
>
Marek