Hi,
The -fgnat-encodings=minimal switch tells the compiler to generate motly pure
DWARF for the GNAT compiler and it contains some bugs related to discriminated
record types with variant part.
Tested on x86-64/Linux, OK for the mainline?
2020-05-05 Eric Botcazou <ebotca...@adacore.com>
Pierre-Marie de Rodat <dero...@adacore.com>
* dwarf2out.c (add_data_member_location_attribute): Take into account
the variant part offset in the computation of the data bit offset.
(add_bit_offset_attribute): Remove CTX parameter. Pass a new context
in the call to field_byte_offset.
(gen_field_die): Adjust call to add_bit_offset_attribute and remove
confusing assertion.
(analyze_variant_discr): Deal with boolean subtypes.
2020-05-05 Eric Botcazou <ebotca...@adacore.com>
* gnat.dg/debug16.adb: New test.
--
Eric Botcazou
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 787340e9279..396446f7670 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3828,8 +3828,7 @@ static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree,
static void add_subscript_info (dw_die_ref, tree, bool);
static void add_byte_size_attribute (dw_die_ref, tree);
static void add_alignment_attribute (dw_die_ref, tree);
-static inline void add_bit_offset_attribute (dw_die_ref, tree,
- struct vlr_context *);
+static void add_bit_offset_attribute (dw_die_ref, tree);
static void add_bit_size_attribute (dw_die_ref, tree);
static void add_prototyped_attribute (dw_die_ref, tree);
static void add_abstract_origin_attribute (dw_die_ref, tree);
@@ -19118,6 +19117,7 @@ struct vlr_context
QUAL_UNION_TYPE nodes. Each time such a structure is passed to a
function processing a FIELD_DECL, it is required to be non null. */
tree struct_type;
+
/* When generating a variant part in a RECORD_TYPE (i.e. a nested
QUAL_UNION_TYPE), this holds an expression that computes the offset for
this variant part as part of the root record (in storage units). For
@@ -19456,9 +19456,13 @@ add_data_member_location_attribute (dw_die_ref die,
to dwarf_version >= 4 once most consumers catched up. */
if (dwarf_version >= 5
&& TREE_CODE (decl) == FIELD_DECL
- && DECL_BIT_FIELD_TYPE (decl))
+ && DECL_BIT_FIELD_TYPE (decl)
+ && (ctx->variant_part_offset == NULL_TREE
+ || TREE_CODE (ctx->variant_part_offset) == INTEGER_CST))
{
tree off = bit_position (decl);
+ if (ctx->variant_part_offset)
+ off = bit_from_pos (ctx->variant_part_offset, off);
if (tree_fits_uhwi_p (off) && get_AT (die, DW_AT_bit_size))
{
remove_AT (die, DW_AT_byte_size);
@@ -21095,14 +21099,12 @@ add_alignment_attribute (dw_die_ref die, tree tree_node)
exact location of the "containing object" for a bit-field is rather
complicated. It's handled by the `field_byte_offset' function (above).
- CTX is required: see the comment for VLR_CONTEXT.
-
Note that it is the size (in bytes) of the hypothetical "containing object"
which will be given in the DW_AT_byte_size attribute for this bit-field.
(See `byte_size_attribute' above). */
static inline void
-add_bit_offset_attribute (dw_die_ref die, tree decl, struct vlr_context *ctx)
+add_bit_offset_attribute (dw_die_ref die, tree decl)
{
HOST_WIDE_INT object_offset_in_bytes;
tree original_type = DECL_BIT_FIELD_TYPE (decl);
@@ -21111,7 +21113,10 @@ add_bit_offset_attribute (dw_die_ref die, tree decl, struct vlr_context *ctx)
HOST_WIDE_INT highest_order_field_bit_offset;
HOST_WIDE_INT bit_offset;
- field_byte_offset (decl, ctx, &object_offset_in_bytes);
+ /* The containing object is within the DECL_CONTEXT. */
+ struct vlr_context ctx = { DECL_CONTEXT (decl), NULL_TREE };
+
+ field_byte_offset (decl, &ctx, &object_offset_in_bytes);
/* Must be a field and a bit field. */
gcc_assert (original_type && TREE_CODE (decl) == FIELD_DECL);
@@ -24279,16 +24284,11 @@ gen_field_die (tree decl, struct vlr_context *ctx, dw_die_ref context_die)
{
add_byte_size_attribute (decl_die, decl);
add_bit_size_attribute (decl_die, decl);
- add_bit_offset_attribute (decl_die, decl, ctx);
+ add_bit_offset_attribute (decl_die, decl);
}
add_alignment_attribute (decl_die, decl);
- /* If we have a variant part offset, then we are supposed to process a member
- of a QUAL_UNION_TYPE, which is how we represent variant parts in
- trees. */
- gcc_assert (ctx->variant_part_offset == NULL_TREE
- || TREE_CODE (DECL_FIELD_CONTEXT (decl)) != QUAL_UNION_TYPE);
if (TREE_CODE (DECL_FIELD_CONTEXT (decl)) != UNION_TYPE)
add_data_member_location_attribute (decl_die, decl, ctx);
@@ -24883,7 +24883,9 @@ analyze_variants_discr (tree variant_part_decl,
else if ((candidate_discr
= analyze_discr_in_predicate (match_expr, struct_type))
- && TREE_TYPE (candidate_discr) == boolean_type_node)
+ && (TREE_TYPE (candidate_discr) == boolean_type_node
+ || TREE_TYPE (TREE_TYPE (candidate_discr))
+ == boolean_type_node))
{
/* We are matching: <discr_field> for a boolean discriminant.
This sub-expression matches boolean_true_node. */
-- { dg-do compile }
-- { dg-skip-if "No Dwarf" { { hppa*-*-hpux* } && { ! lp64 } } }
-- { dg-options "-cargs -O0 -g -dA -fgnat-encodings=minimal -margs" }
procedure Debug16 is
type Number_T (Exists : Boolean := False) is
record
case Exists is
when True =>
Value : Natural range 0 .. 255;
when False =>
null;
end case;
end record;
pragma Pack (Number_T);
X : Number_T;
begin
X := (Exists => True, Value => 10);
if X.Exists then -- STOP
X.Value := X.Value + 1;
end if;
end;
-- { dg-final { scan-assembler-times "DW_AT_discr" 4 } }