[Dwarf-Discuss] Unnamed zero sized bit-fields (Re: Corner-cases with bitfields)

Pedro Alves alves.ped at gmail.com
Tue May 10 04:10:31 PDT 2022

On 2022-05-06 18:11, Lancelot SIX via Dwarf-Discuss wrote:

> 2 - Unnamed zero sized bitfield
> Another case we met is related to unnamed fields with a size of 0 bits.
> Such field is defined in the c++ standard as (in 9.6 Bit-Fields):
>  > As a special case, an unnamed bit-field with a width of zero
>  > specifies alignment of the next bit-field at an allocation unit
>  > boundary
> If we now consider an extended version of our previous example:
>      struct Foo
>      {
>        char a : 8;
>        char : 0;
>        char b : 8,
>      };
> Neither GCC nor Clang give any information about the unnamed bitfield.
> As for the previous case, the presence of such field impacts how
> arguments are passed during function calls on our target, leaving the
> debugger unable to properly decide how to handle such cases.
> As for the previous case, both compilers can properly describe Foo's
> memory layout using DW_AT_bit_offset.
> It seems that such 0-sized field also has impact on ABI on other targets
> such as armv7hl and aarch64 as discussed in [2].  Should the DWARF
> specification give some guidance on how to handle such situation?
> All thoughts on those cases are welcome.

In DWARF 5, we have:

 Data Member Entries
A data member (as opposed to a member function) is represented by a
debugging information entry with the tag DW_TAG_member. The member
entry for a named member has a DW_AT_name attribute whose value is a
null-terminated string containing the member name. If the member entry
describes an anonymous union, the name attribute is omitted or the value of the
attribute consists of a single zero byte."

I didn't find anything that would prevent a producer from emitting an
unnamed bit-field member.  Ignoring the 0-size special case for the moment,
neither GCC nor Clang emit the unnamed bit-field in this case either:

    struct Foo
      char a : 8;
      char : 8;
      char b : 8;

I suppose you could call it QoI to emit an unnamed field for this unnamed bit-field,
in the same vein of what I mentioned earlier about making it possible for the debugger to
reconstruct the original type (a debugger could infer the size of the unnamed bit-field
from the gap, but not its declared type).  I didn't find wording in the spec that
would prevent it.

>From that angle, unnamed zero-sized bit-fields could also be emitted, ISTM that it's
technically possible to describe it with current DWARF, though, consumer-implementation-wise,
a consumer may need to be able to distinguish "no DW_AT_bit_size present" vs
"DW_AT_bit_size present and value is 0".  Anyone see an issue with making that distinction
DWARF-spec wise?  Could that result in ambiguities somewhere?  I don't think that GDB makes
such a distinction currently, I think internally "bit size == 0" means not a bit field,
but that would be changed, of course, it's implementation detail.

For some reason (maybe because of the weird "single zero byte" special case?), the
wording above from 5.7.6 describes what to do with anonymous unions, kind of giving
the impression that it could also specify what is expected with other unnamed fields
such as unnamed bit-fields.

OTOH, we have "D.2.8 C/C++ Bit-Field Examples", where the spec says "Bit fields in C and C++
typically require the use of the DW_AT_data_bit_offset and DW_AT_bit_size attributes.".  
It then goes on to give examples of big- and little-endian machines.  Maybe this chapter would
be the spot where the spec would give the example of what to do with unnamed bit-fields
of 0 size, as _it is_ a special case described in the C++ language spec, i.e., has meaning
at the language level that is lost otherwise, and the D.2.8 chapter in the DWARF spec is
specifically about C/C++.

Or this is yet another case that people would prefer to leave things as is DWARF-spec-wise
and we should go file bug reports with GCC and Clang?

Pedro Alves

More information about the Dwarf-Discuss mailing list