Files
binutils-gdb/gdb/testsuite/gdb.ada/negative-bit-offset
Tom Tromey 21b25b168d Fix regression with DW_AT_bit_offset handling
Internal AdaCore testing using -gdwarf-4 found a spot where GCC will
emit a negative DW_AT_bit_offset.  However, my recent signed/unsigned
changes assumed that this value had to be positive.

I feel this bug somewhat invalidates my previous thinking about how
DWARF attributes should be handled.

In particular, both GCC and LLVM at understand that a negative bit
offset can be generated -- but for positive offsets they might use a
smaller "data" form, which is expected not to be sign-extended.  LLVM
has similar code but GCC does:

  if (bit_offset < 0)
    add_AT_int (die, DW_AT_bit_offset, bit_offset);
  else
    add_AT_unsigned (die, DW_AT_bit_offset, (unsigned HOST_WIDE_INT) bit_offset);

What this means is that this attribute is "signed but default
unsigned".

To fix this, I've added a new attribute::confused_constant method.
This should be used when a constant value might be signed, but where
narrow forms (e.g., DW_FORM_data1) should *not* cause sign extension.

I examined the GCC and LLVM DWARF writers to come up with the list of
attributes where this applies, namely DW_AT_bit_offset,
DW_AT_const_value and DW_AT_data_member_location (GCC only, but LLVM
always emits it as unsigned, so we're safe here).

This patch corrects the bug and imports the relevant test case.

Regression tested on x86-64 Fedora 41.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32680
Bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118837
Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-06-06 10:13:23 -06:00
..