From 4ec9d0962371c134d881d7dcfcef5effc8ed847f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 3 Dec 2020 00:29:46 +0100 Subject: [PATCH] dwarf2out: Fix up add_scalar_info not to create invalid DWARF As discussed in https://sourceware.org/bugzilla/show_bug.cgi?id=26987 , for very large bounds (which don't fit into HOST_WIDE_INT) GCC emits invalid DWARF. In DWARF2, DW_AT_{lower,upper}_bound were constant reference class. In DWARF3 they are block constant reference and the Static and Dynamic Properties of Types chapter says: "For a block, the value is interpreted as a DWARF expression; evaluation of the expression yields the value of the attribute." In DWARF4/5 they are constant exprloc reference class. Now, for add_AT_wide we use DW_FORM_data16 (valid in constant class) when -gdwarf-5, but otherwise just use DW_FORM_block1, which is not constant class, but block. For DWARF3 this means emitting clearly invalid DWARF, because the DW_FORM_block1 should contain a DWARF expression, not random bytes containing the constant directly. For DWARF2/DWARF4/5 it could be considered a GNU extension, but a very badly designed one when it means something different in DWARF3. The following patch uses add_AT_wide only if we know we'll be using DW_FORM_data16, and otherwise wastes 2 extra bytes and emits in there DW_OP_implicit_value before the constant. 2020-12-03 Jakub Jelinek * dwarf2out.c (add_scalar_info): Only use add_AT_wide for 128-bit constants and only in dwarf-5 or later, where DW_FORM_data16 is available. Otherwise use DW_FORM_block*/DW_FORM_exprloc with DW_OP_implicit_value to describe the constant. --- gcc/dwarf2out.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 0a0a7ea..c23a3ca 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -20775,12 +20775,23 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, else add_AT_int (die, attr, TREE_INT_CST_LOW (value)); } - else + else if (dwarf_version >= 5 + && TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (value))) == 128) /* Otherwise represent the bound as an unsigned value with the precision of its type. The precision and signedness of the type will be necessary to re-interpret it unambiguously. */ add_AT_wide (die, attr, wi::to_wide (value)); + else + { + rtx v = immed_wide_int_const (wi::to_wide (value), + TYPE_MODE (TREE_TYPE (value))); + dw_loc_descr_ref loc + = loc_descriptor (v, TYPE_MODE (TREE_TYPE (value)), + VAR_INIT_STATUS_INITIALIZED); + if (loc) + add_AT_loc (die, attr, loc); + } return; } -- 2.7.4