Fix incorrect array bounds with -fgnat-encodings=minimal in DWARF
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 7 May 2021 20:52:18 +0000 (22:52 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Fri, 7 May 2021 21:00:18 +0000 (23:00 +0200)
This makes add_subscript_info query the get_array_descr_info hook for the
actual information when it is defined.

gcc/
* cfgexpand.c (expand_gimple_basic_block): Do not inherit a current
location for the outgoing edges of an empty block.
* dwarf2out.c (add_subscript_info): Retrieve the bounds and index
type by means of the get_array_descr_info langhook, if it is set and
returns true.  Remove obsolete code dealing with unnamed subtypes.
gcc/testsuite/
* gnat.dg/debug18.adb: New test.

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

index 556a0b2..747ca3e 100644 (file)
@@ -6056,7 +6056,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls)
   /* Expand implicit goto and convert goto_locus.  */
   FOR_EACH_EDGE (e, ei, bb->succs)
     {
-      if (e->goto_locus != UNKNOWN_LOCATION)
+      if (e->goto_locus != UNKNOWN_LOCATION || !stmt)
        set_curr_insn_location (e->goto_locus);
       if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
        {
index 871362b..a5ec21a 100644 (file)
@@ -21313,8 +21313,6 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr,
 
 /* Add subscript info to TYPE_DIE, describing an array TYPE, collapsing
    possibly nested array subscripts in a flat sequence if COLLAPSE_P is true.
-   Note that the block of subscript information for an array type also
-   includes information about the element type of the given array type.
 
    This function reuses previously set type and bound information if
    available.  */
@@ -21322,9 +21320,21 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr,
 static void
 add_subscript_info (dw_die_ref type_die, tree type, bool collapse_p)
 {
-  unsigned dimension_number;
-  tree lower, upper;
   dw_die_ref child = type_die->die_child;
+  struct array_descr_info info;
+  int dimension_number;
+
+  if (lang_hooks.types.get_array_descr_info)
+    {
+      memset (&info, 0, sizeof (info));
+      if (lang_hooks.types.get_array_descr_info (type, &info))
+       /* Fortran sometimes emits array types with no dimension.  */
+       gcc_assert (info.ndimensions >= 0
+                   && info.ndimensions
+                      <= DWARF2OUT_ARRAY_DESCR_INFO_MAX_DIMEN);
+    }
+  else
+    info.ndimensions = 0;
 
   for (dimension_number = 0;
        TREE_CODE (type) == ARRAY_TYPE && (dimension_number == 0 || collapse_p);
@@ -21372,26 +21382,22 @@ add_subscript_info (dw_die_ref type_die, tree type, bool collapse_p)
       if (domain)
        {
          /* We have an array type with specified bounds.  */
-         lower = TYPE_MIN_VALUE (domain);
-         upper = TYPE_MAX_VALUE (domain);
+         tree lower = TYPE_MIN_VALUE (domain);
+         tree upper = TYPE_MAX_VALUE (domain);
+         tree index_type = TREE_TYPE (domain);
 
-         /* Define the index type.  */
-         if (TREE_TYPE (domain)
-             && !get_AT (subrange_die, DW_AT_type))
+         if (dimension_number <= info.ndimensions - 1)
            {
-             /* ??? This is probably an Ada unnamed subrange type.  Ignore the
-                TREE_TYPE field.  We can't emit debug info for this
-                because it is an unnamed integral type.  */
-             if (TREE_CODE (domain) == INTEGER_TYPE
-                 && TYPE_NAME (domain) == NULL_TREE
-                 && TREE_CODE (TREE_TYPE (domain)) == INTEGER_TYPE
-                 && TYPE_NAME (TREE_TYPE (domain)) == NULL_TREE)
-               ;
-             else
-               add_type_attribute (subrange_die, TREE_TYPE (domain),
-                                   TYPE_UNQUALIFIED, false, type_die);
+             lower = info.dimen[dimension_number].lower_bound;
+             upper = info.dimen[dimension_number].upper_bound;
+             index_type = info.dimen[dimension_number].bounds_type;
            }
 
+         /* Define the index type.  */
+         if (index_type && !get_AT (subrange_die, DW_AT_type))
+           add_type_attribute (subrange_die, index_type, TYPE_UNQUALIFIED,
+                               false, type_die);
+
          /* ??? If upper is NULL, the array has unspecified length,
             but it does have a lower bound.  This happens with Fortran
               dimension arr(N:*)
@@ -21399,8 +21405,9 @@ add_subscript_info (dw_die_ref type_die, tree type, bool collapse_p)
             to produce useful results, go ahead and output the lower
             bound solo, and hope the debugger can cope.  */
 
-         if (!get_AT (subrange_die, DW_AT_lower_bound))
+         if (lower && !get_AT (subrange_die, DW_AT_lower_bound))
            add_bound_info (subrange_die, DW_AT_lower_bound, lower, NULL);
+
          if (!get_AT (subrange_die, DW_AT_upper_bound)
              && !get_AT (subrange_die, DW_AT_count))
            {
@@ -22129,6 +22136,7 @@ decl_start_label (tree decl)
 /* For variable-length arrays that have been previously generated, but
    may be incomplete due to missing subscript info, fill the subscript
    info.  Return TRUE if this is one of those cases.  */
+
 static bool
 fill_variable_array_bounds (tree type)
 {
diff --git a/gcc/testsuite/gnat.dg/debug18.adb b/gcc/testsuite/gnat.dg/debug18.adb
new file mode 100644 (file)
index 0000000..59ba54d
--- /dev/null
@@ -0,0 +1,20 @@
+-- { dg-do compile }
+-- { dg-skip-if "No Dwarf" { { hppa*-*-hpux* } && { ! lp64 } } }
+-- { dg-options "-cargs -O0 -g -dA -fgnat-encodings=minimal -margs" }
+
+procedure Debug18 is
+
+   procedure Check (Size : Integer) is
+      type Bit_Array_Type is array (1 .. Size) of boolean;
+      pragma Pack (Bit_Array_Type);
+
+      Bits : Bit_Array_Type := (others => False);
+   begin
+      Bits (Bits'First) := True;
+   end;
+  
+begin
+   Check (Size => 9);
+end;
+
+-- { dg-final { scan-assembler-not "DW_AT_lower_bound" } }