Fix a few DWARF bugs with -fgnat-encodings=minimal
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 5 May 2020 10:35:00 +0000 (12:35 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 7 May 2020 08:54:09 +0000 (10:54 +0200)
The -fgnat-encodings=minimal switch tells the compiler to generate mostly
pure DWARF for the GNAT compiler and it contains some bugs related to
discriminated record types with variant part.

* dwarf2out.c (add_data_member_location_attribute): Account for
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.

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/debug16.adb [new file with mode: 0644]

index 89d4ea348e9878005625f63f3fa678946b956add..19d5167aa6b4780800309168581262ae5cdcb3dc 100644 (file)
@@ -1,3 +1,14 @@
+2020-05-07  Eric Botcazou  <ebotcazou@adacore.com>
+            Pierre-Marie de Rodat  <derodat@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-07  Martin Liska  <mliska@suse.cz>
 
        * lto-wrapper.c: Split arguments of MAKE environment
index 787340e92793a9b70b53b04c900bf4f1f2d29e44..396446f7670ad8274355cebfc2b2643115d84944 100644 (file)
@@ -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.  */
index b6b0441de6a4835d9946944fb9b8062a9cf4b09c..22ad03d914e5590d3f03164ae04b4023ac9e7006 100644 (file)
@@ -1,3 +1,7 @@
+2020-05-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/debug16.adb: New test.
+
 2020-05-06  Marek Polacek  <polacek@redhat.com>
 
        PR c++/94938
diff --git a/gcc/testsuite/gnat.dg/debug16.adb b/gcc/testsuite/gnat.dg/debug16.adb
new file mode 100644 (file)
index 0000000..8752002
--- /dev/null
@@ -0,0 +1,27 @@
+--  { 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 } }