On Wed, Jun 25, 2025 at 01:05:39PM -0400, Jason Merrill wrote:
> On 5/21/25 10:14 PM, Nathaniel Shead wrote:
> > This patch isn't currently necessary with how I've currently done the
> > follow-up patches, but is needed for avoiding any potential issues in
> > the future with DECL_CONTEXT'ful types getting created in the compiler
> > with no names on the fields.  (For instance, this change would make much
> > of r15-7342-gd3627c78be116e unnecessary.)
> > 
> > It does take up another flag though in the frontend though.  Another
> > possible approach would be to instead do a walk through all the fields
> > first to see if this is the target of a DECL_BIT_FIELD_REPRESENTATIVE;
> > thoughts?  Or would you prefer to skip this patch entirely?
> 
> It seems like the only way to reach such a FIELD_DECL is through
> DECL_BIT_FIELD_REPRESENTATIVE, so we ought to be able to use that without
> adding another walk?

Fair enough, how does this look instead?  Bootstrapped and tested (so
far just modules.exp) on x86_64-pc-linux-gnu, OK for trunk if full
regtest passes?

-- >8 --

Subject: [PATCH] c++/modules: Make bitfield storage unit detection more robust

Modules streaming needs to handle these differently from other unnamed
FIELD_DECLs that are streamed for internal RECORD_DECLs, and there
doesn't seem to be a good way to detect this case otherwise.

This matters only to allow for compiler-generated type definitions that
build FIELD_DECLs with no name, as otherwise they get confused.
Currently the only such types left I hadn't earlier fixed by giving
names to are contextless, for which we have an early check to mark their
fields as MK_unique anyway, but there may be other cases in the future.

gcc/cp/ChangeLog:

        * module.cc (trees_out::walking_bit_field_unit): New flag.
        (trees_out::trees_out): Initialize it.
        (trees_out::core_vals): Set it.
        (trees_out::get_merge_kind): Use it, move previous ad-hoc check
        into assertion.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
 gcc/cp/module.cc | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 42a1b83e164..7bc3e576293 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -3097,6 +3097,9 @@ private:
   unsigned section;
   bool writing_local_entities; /* Whether we might walk into a TU-local
                                   entity we need to emit placeholders for.  */
+  bool walking_bit_field_unit;  /* Whether we're walking the underlying
+                                  storage for a bit field.  There's no other
+                                  great way to detect this.  */
 #if CHECKING_P
   int importedness;            /* Checker that imports not occurring
                                   inappropriately.  +ve imports ok,
@@ -3263,7 +3266,7 @@ trees_out::trees_out (allocator *mem, module_state 
*state, depset::hash &deps,
                      unsigned section)
   :parent (mem), state (state), tree_map (500),
    dep_hash (&deps), ref_num (0), section (section),
-   writing_local_entities (false)
+   writing_local_entities (false), walking_bit_field_unit (false)
 {
 #if CHECKING_P
   importedness = 0;
@@ -6512,7 +6515,10 @@ trees_out::core_vals (tree t)
     case FIELD_DECL:
       WT (t->field_decl.offset);
       WT (t->field_decl.bit_field_type);
-      WT (t->field_decl.qualifier); /* bitfield unit.  */
+      {
+       auto ovr = make_temp_override (walking_bit_field_unit, true);
+       WT (t->field_decl.qualifier); /* bitfield unit.  */
+      }
       WT (t->field_decl.bit_offset);
       WT (t->field_decl.fcontext);
       WT (t->decl_common.initial);
@@ -11268,15 +11274,16 @@ trees_out::get_merge_kind (tree decl, depset *dep)
              return MK_named;
            }
 
-         if (!DECL_NAME (decl)
-             && !RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
-             && !DECL_BIT_FIELD_REPRESENTATIVE (decl))
+         if (walking_bit_field_unit)
            {
              /* The underlying storage unit for a bitfield.  We do not
                 need to dedup it, because it's only reachable through
                 the bitfields it represents.  And those are deduped.  */
              // FIXME: Is that assertion correct -- do we ever fish it
              // out and put it in an expr?
+             gcc_checking_assert (!DECL_NAME (decl)
+                                  && !RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
+                                  && !DECL_BIT_FIELD_REPRESENTATIVE (decl));
              gcc_checking_assert ((TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
                                    ? TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
                                    : TREE_CODE (TREE_TYPE (decl)))
-- 
2.47.0

Reply via email to