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> >");

Reply via email to