https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128024
Bug ID: 128024
Summary: [DebugInfo] emits invalid DW_OP_and operands with
-mx32
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: ---
With -mx32 -Og -g -gdwarf-5, GCC emits a DW_OP_and with incompatible
operand types in the DWARF location expression for count.
The -mx32 option selects the x86-64 ILP32 ABI, also called x32. It uses
x86-64 instructions and registers, but pointers and the DWARF address
size are 32 bits. unsigned long long remains 64 bits, so GCC uses an
explicit DWARF base type to describe values wider than the generic
stack type.
Reproducer source (repro.c):
typedef unsigned long long u64;
__attribute__ ((noinline, noclone)) unsigned long
clz_vla_bound (u64 input)
{
u64 count = (u64) __builtin_clzll (input | 1ULL);
unsigned char data[count + 1];
__asm__ volatile ("" : : "m" (data) : "memory");
return sizeof (data);
}
The input | 1ULL ensures that the argument to __builtin_clzll is nonzero.
Compile to an object file:
gcc -mx32 -Og -g -gdwarf-5 -c repro.c -o repro.o
The loop implementing CLZ in the location expression contains:
DW_OP_dup
DW_OP_const8u 0x8000000000000000
DW_OP_and
DW_OP_dup copies a stack entry with the 8-byte unsigned long long base
type. DW_OP_const8u pushes a generic-type value: the eight-byte encoding
of its operand does not give the stack entry an unsigned long long base
type. DW_OP_and therefore receives one explicitly typed operand and one
generic operand.
DWARF 5 section 2.5.1.4 requires both operands of DW_OP_and to have the
same type: either both generic or both the same base type. The generated
expression violates this requirement.
Compiler Explorer reproduction using the GCC snapshot:
https://godbolt.org/z/Tz5sxGM9e