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.

Reply via email to