Fix signedness issue in DWARF functions (1)
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 28 May 2021 17:18:37 +0000 (19:18 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Thu, 3 Jun 2021 10:41:20 +0000 (12:41 +0200)
commite26b748a62e5bc59f6671faab75f737503c87319
tree608cb78d94fa4cfef5b80576636720c70edab601
parentd9a83b99349071e1c6e78df7fea3424338390d5e
Fix signedness issue in DWARF functions (1)

The compiler can synthesize DWARF functions to describe the location and
size of components in discriminated record types with variant part in Ada,
but a limitation is that most quantities must have DWARF2_ADDR_SIZE or
else be the result of a zero-extension to DWARF2_ADDR_SIZE of a smaller
quantity, as documented in loc_list_from_tree_1:

  /* ??? Most of the time we do not take proper care for sign/zero
     extending the values properly.  Hopefully this won't be a real
     problem...  */

In Ada discriminants may be either signed or unsigned, so this limitation
is problematic.  Therefore the attached patch adds a strict_signedness
field to the loc_descr_context that is passed around in parts of the DWARF
back-end and changes loc_list_from_tree_1 to act upon it being set to true.
It also contains an optimization to avoid emitting useless comparisons.

gcc/
* dwarf2out.c (scompare_loc_descriptor): Fix head comment.
(is_handled_procedure_type): Likewise.
(struct loc_descr_context): Add strict_signedness field.
(resolve_args_picking_1): Deal with DW_OP_[GNU_]deref_type,
DW_OP_[GNU_]convert and DW_OP_[GNU_]reinterpret.
(resolve_args_picking): Minor tweak.
(function_to_dwarf_procedure): Initialize strict_signedness field.
(type_byte_size): Likewise.
(field_byte_offset): Likewise.
(gen_descr_array_type_die): Likewise.
(gen_variant_part): Likewise.
(loc_list_from_tree_1) <CALL_EXPR>: Tidy up and set strict_signedness
to true when a context is present before evaluating the arguments.
<COND_EXPR>: Do not generate a useless comparison with zero.
When dereferencing an address, if strict_signedness is true and the
type is small and signed, use DW_OP_deref_type to do the dereference
and then DW_OP_convert to convert back to the generic type.
gcc/dwarf2out.c