https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127679
Bug ID: 127679
Summary: RTL do_binop 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 (tested on x86-64 Linux) emits an invalid DWARF
expression for value in the following repro.c:
typedef unsigned long long u64;
__attribute__((noinline, noclone)) u64
bit_and (double input)
{
u64 value = (u64) input & 0xff;
__asm__ volatile ("nop" ::: "memory");
return 0;
}
int
main (void)
{
return (int) bit_and (1.25);
}
Compile with that GCC:
gcc -O2 -g -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_const1u 255
DW_OP_and
DW_OP_stack_value
The referenced double and unsigned integer base types are both 8 bytes.
DW_OP_convert leaves an unsigned base-typed value, while DW_OP_const1u
pushes a generic value. DW_OP_and therefore consumes operands with
different DWARF types. DWARF 5 ยง2.5.1.4 requires both operands to be generic
or to have the same base type; matching bit widths are insufficient.
GDB reports "Incompatible types on DWARF stack" when printing value at
that point.
The cause is the RTL do_binop path in mem_loc_descriptor in
gcc/dwarf2out.cc. The AND case concatenates the two operand descriptions
and emits DW_OP_and without reconciling their DWARF stack types. The MINUS,
MULT, UMOD, IOR and XOR cases share this path. Both operands need compatible
types before the binary opcode is emitted.