On Thu, Mar 12, 2026 at 09:50:08AM -0400, Jason Merrill wrote:
> > {,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?
> > 
> > 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>.
> 
> How about <anonymous union>?

So like this then?
Left the <unnamed member> as fallback for now at least for anonymous structs
(for which we really need to add test coverage and tweak reflect.cc to
probably handle it like anonymous unions) or perhaps other cases.

Tested on x86_64-linux with
GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 make -j32 -k check-g++ 
RUNTESTFLAGS="dg.exp='reflect/* expansion-stmt*'"
Ok for trunk if it passes full bootstrap/regtest?

2026-03-12  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>.

--- gcc/cp/reflect.cc.jj        2026-03-05 09:19:22.173774816 +0100
+++ gcc/cp/reflect.cc   2026-03-12 15:44:28.123749635 +0100
@@ -3604,7 +3604,14 @@ 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 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);
--- 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-12 
15:45: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::<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> >");
--- 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-12 
15:46: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::<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> >");


        Jakub

Reply via email to