https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66728
Bug ID: 66728
Summary: CONST_WIDE_INT causes corrupted DWARF debug info
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: debug
Assignee: unassigned at gcc dot gnu.org
Reporter: uweigand at gcc dot gnu.org
Target Milestone: ---
Compiling the following test case:
__uint128_t test(void)
{
static const __uint128_t two127 = ((__uint128_t) 1) << 127;
return two127;
}
on x86_64-linux (or ppc64le-linux) with -O -S -g -dA results in:
.uleb128 0x2 # (DIE (0x2d) DW_TAG_subprogram)
# DW_AT_external
.long .LASF3 # DW_AT_name: "test"
[snip]
.uleb128 0x3 # (DIE (0x4e) DW_TAG_variable)
.long .LASF4 # DW_AT_name: "two127"
.byte 0x1 # DW_AT_decl_file (xxx.i)
.byte 0x4 # DW_AT_decl_line
.long 0x61 # DW_AT_type
.byte 0 # end of children of DIE 0x2d
But abbreviation 3 (used for the 0x4e DIE) reads:
.uleb128 0x3 # (abbrev code)
.uleb128 0x34 # (TAG: DW_TAG_variable)
.byte 0 # DW_children_no
.uleb128 0x3 # (DW_AT_name)
.uleb128 0xe # (DW_FORM_strp)
.uleb128 0x3a # (DW_AT_decl_file)
.uleb128 0xb # (DW_FORM_data1)
.uleb128 0x3b # (DW_AT_decl_line)
.uleb128 0xb # (DW_FORM_data1)
.uleb128 0x49 # (DW_AT_type)
.uleb128 0x13 # (DW_FORM_ref4)
.uleb128 0x1c # (DW_AT_const_value)
.uleb128 0xa # (DW_FORM_block1)
.byte 0
.byte 0
So the variable DIE should have an DW_AT_const_value attribute encoded as
DW_FORM_block1. This makes sense, since the variable was optimized away due to
being constant, and the size of the constant is 16 bytes.
However, the code in .debug_info to construct the DIE does not emit any
DW_FORM_block1; in fact, it does not emit *anything* where the
DW_AT_const_value is expected. This causes the resulting debug info to be
corrupted, and tools operating on this info will emit errors (or even crash).
On ppc64le-linux (but not x86_64-linux), the same problem occurs with GCC 5 as
well. The difference seems to be that x86_64 in GCC 5 uses a CONST_DOUBLE
instead of a CONST_WIDE_INT to represent that 128-bit constant.