https://gcc.gnu.org/g:d497ded4fb603b0494b7ede96dd983be9c3cacf1
commit r16-8071-gd497ded4fb603b0494b7ede96dd983be9c3cacf1 Author: Jakub Jelinek <[email protected]> Date: Fri Mar 13 09:13:09 2026 +0100 c++: Fix up *display_string_of on anon union member [PR124388] {,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 by printing %T::<anonymous union> for anon union NSDM and %T::<unnamed member> for anything else unnamed (e.g. anon struct NSDM). 2026-03-13 Jakub Jelinek <[email protected]> PR c++/124388 * reflect.cc (eval_display_string_of): Only print <unnmamed bit-field> for DECL_UNNAMED_BIT_FIELD, for anon union print <anonymous union>, 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>. Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/reflect.cc | 9 ++++++++- gcc/testsuite/g++.dg/reflect/display_string_of1.C | 4 ++++ gcc/testsuite/g++.dg/reflect/u8display_string_of1.C | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index c1d1b36047d8..2e18d2ce99d4 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -3629,7 +3629,14 @@ eval_display_string_of (location_t loc, const constexpr_ctx *ctx, tree r, 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 if (ANON_UNION_TYPE_P (TREE_TYPE (r))) + pp_printf (&pp, "%T::<anonymous union>", DECL_CONTEXT (r)); + else + pp_printf (&pp, "%T::<unnamed member>", DECL_CONTEXT (r)); + } else if (kind == REFLECT_BASE) { tree d = direct_base_derived (r); diff --git a/gcc/testsuite/g++.dg/reflect/display_string_of1.C b/gcc/testsuite/g++.dg/reflect/display_string_of1.C index b88828fec39e..b2f2950a5397 100644 --- a/gcc/testsuite/g++.dg/reflect/display_string_of1.C +++ b/gcc/testsuite/g++.dg/reflect/display_string_of1.C @@ -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], T &e) 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::<anonymous union>"); 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::<anonymous union>"); 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> >"); diff --git a/gcc/testsuite/g++.dg/reflect/u8display_string_of1.C b/gcc/testsuite/g++.dg/reflect/u8display_string_of1.C index 693162e3bb1b..bce7db52a176 100644 --- a/gcc/testsuite/g++.dg/reflect/u8display_string_of1.C +++ b/gcc/testsuite/g++.dg/reflect/u8display_string_of1.C @@ -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], T &e) 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::<anonymous union>"); 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::<anonymous union>"); 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> >");
