https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127676
Bug ID: 127676
Summary: resolve_addr_in_expr rewrite produces invalid DWARF
expressions
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: debug
Assignee: unassigned at gcc dot gnu.org
Reporter: wujielun402 at gmail dot com
Target Milestone: ---
The latest GCC mainline on x86-64 GNU/Linux emits an invalid DWARF 5
location expression for value in the following repro.c:
typedef unsigned long long u64;
__attribute__((noinline, noclone)) u64
bad_large_addend (double input)
{
u64 value = (u64) input + 0x100000000ULL;
__asm__ volatile ("nop" ::: "memory");
return 0;
}
int
main (void)
{
return (int) bad_large_addend (1.375);
}
Compile with that GCC:
gcc -O2 -g -gdwarf-5 -fvar-tracking-assignments -fno-pie -no-pie
repro.c -o repro
At the nop, the expression is (base-type references shown symbolically):
DW_OP_regval_type XMM0 <double>
DW_OP_convert <unsigned long>
DW_OP_lit16
DW_OP_lit28
DW_OP_shl
DW_OP_plus
DW_OP_stack_value
The referenced double and unsigned integer base types are both 8 bytes.
DW_OP_lit16 and DW_OP_lit28 push generic values, so DW_OP_shl also
produces a generic value. DW_OP_plus therefore consumes an unsigned
base-typed value and a generic constant (16 << 28). DWARF 5 ยง2.5.1.4
requires both operands to be generic or to have the same base type. Equal
bit widths do not satisfy this type requirement; the expression is invalid.
GDB reports "Incompatible types on DWARF stack" when printing value at
that point.
The cause is the size optimization in resolve_addr_in_expr in
gcc/dwarf2out.cc: it replaces the type-preserving DW_OP_plus_uconst with
a generic constant expression and DW_OP_plus. The rewrite needs to
preserve the stack operand's type.