(Ada) Fix print of array using non-contiguous enumeration indexes

Consider the following code:

  type Index is (Index1, Index2);
  Size : constant Integer := 10;
  for Index use (Index1 => 1, Index2 => Size);
  type Array_Index_Enum is array (Index) of Integer;
  my_table : Array_Index_Enum :=(others => 42);

When compiling the code above with a compiler where the GNAT encodings
are turned off (which can be temporarily emulated by using the compiler
switch -fgnat-encodings=minimal), printing this table in gdb leads to:

  (gdb) p my_table
  $1 = (42, 42, 4203344, 10, -8320, 32767, 4203465, 0, 0, 0)

The displayed content is wrong since the handling part believes
that the length of the array is max index value (10) minus the
first index value (1) i+ 1 = 10 which is wrong since index are not
contiguous in this case.

The right behavior is to detect that the array is using enumeration
index hence parse the enumeration values in order to get the number
of indexes in this array (2 indexes here).

This patch fixes this issue and changes the output as follow:

  (gdb) p my_table
  $1 = (42, 42)

gdb/ChangeLog:

        * ada-valprint.c (val_print_packed_array_elements): Use
        proper number of elements when printing an array indexed
        by an enumeration type.

gdb/testsuite/ChangeLog (Joel Brobecker  <brobecker@adacore.com>):

        * gdb.ada/arr_enum_idx_w_gap.exp
        * gdb.ada/arr_enum_idx_w_gap/foo_q418_043.adb

Tested on x86_64-linux.
This commit is contained in:
Xavier Roirand 2018-01-07 23:56:36 -05:00 committed by Joel Brobecker
parent e09efd5931
commit 04bafb1ed0
5 changed files with 102 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2018-01-08 Xavier Roirand <roirand@adacore.com>
* ada-valprint.c (val_print_packed_array_elements): Use
proper number of elements when printing an array indexed
by an enumeration type.
2018-01-07 Simon Marchi <simon.marchi@polymtl.ca>
* dwarf2read.c (struct dwarf2_cu) <dwarf2_per_objfile>: Remove.

View File

@ -141,11 +141,45 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
{
LONGEST high;
struct type *base_index_type;
if (get_discrete_bounds (index_type, &low, &high) < 0)
len = 1;
else
len = high - low + 1;
if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
base_index_type = TYPE_TARGET_TYPE (index_type);
else
base_index_type = index_type;
if (TYPE_CODE (base_index_type) == TYPE_CODE_ENUM)
{
LONGEST low_pos, high_pos;
/* Non-contiguous enumerations types can by used as index types
so the array length is computed from the positions of the
first and last literal in the enumeration type, and not from
the values of these literals. */
if (!discrete_position (base_index_type, low, &low_pos)
|| !discrete_position (base_index_type, high, &high_pos))
{
warning (_("unable to get positions in array, use bounds instead"));
low_pos = low;
high_pos = high;
}
/* The array length should normally be HIGH_POS - LOW_POS + 1.
But in Ada we allow LOW_POS to be greater than HIGH_POS for
empty arrays. In that situation, the array length is just zero,
not negative! */
if (low_pos > high_pos)
len = 0;
else
len = high_pos - low_pos + 1;
}
}
i = 0;

View File

@ -1,3 +1,8 @@
2018-01-08 Joel Brobecker <brobecker@adacore.com>
* gdb.ada/arr_enum_idx_w_gap.exp
* gdb.ada/arr_enum_idx_w_gap/foo_q418_043.adb
2018-01-05 Pedro Alves <palves@redhat.com>
PR gdb/18653

View File

@ -0,0 +1,33 @@
# Copyright 2018 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
load_lib "ada.exp"
standard_ada_testfile foo_q418_043
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } {
return -1
}
clean_restart ${testfile}
set bp_location [gdb_get_line_number "BREAK" ${testdir}/foo_q418_043.adb]
if ![runto "foo_q418_043.adb:$bp_location" ] then {
perror "Couldn't run ${testfile}"
return
}
gdb_test "print A" \
" = \\(42, 42\\)"

View File

@ -0,0 +1,24 @@
-- Copyright 2018 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
procedure Foo_Q418_043 is
type Index is (Index1, Index2);
Size : constant Integer := 10;
for Index use (Index1 => 1, Index2 => Size);
type Array_Index_Enum is array (Index) of Integer;
A : Array_Index_Enum :=(others => 42);
begin
A(Index2) := 4242; --BREAK
end Foo_Q418_043;