diff options
author | Tom Tromey <tromey@adacore.com> | 2020-11-04 08:49:16 -0700 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2020-11-04 08:49:17 -0700 |
commit | a7400e443cb4c20aea2c1c4641cb56a913ff7235 (patch) | |
tree | 558f8c5a6b7eb54e3182a396ef50a293cf97a5b6 /gdb/ada-lang.c | |
parent | 75fd6a26f893fbee0ebd665612e115c0735274ab (diff) | |
download | fsf-binutils-gdb-a7400e443cb4c20aea2c1c4641cb56a913ff7235.zip fsf-binutils-gdb-a7400e443cb4c20aea2c1c4641cb56a913ff7235.tar.gz fsf-binutils-gdb-a7400e443cb4c20aea2c1c4641cb56a913ff7235.tar.bz2 |
Fix decoding of multi-dimensional constrained packed arrays
Printing a multi-dimensional constrained packed array in Ada would not
show the correct values. The bug here is that, when decoding the type
of such an array, only the innermost dimension's element bitsize would
be correct. For outer dimensions, the bitsize must account for the
size of each sub-array, but this was not done.
This patch fixes the problem by arranging to compute these sizes after
decoding the array type. I've included a bit more test case than is
strictly necessary -- the current test here was derived from an
internal test, and this patch brings the two into sync.
gdb/ChangeLog
2020-11-04 Tom Tromey <tromey@adacore.com>
* ada-lang.c (recursively_update_array_bitsize): New function.
(decode_constrained_packed_array_type): Call it.
gdb/testsuite/ChangeLog
2020-11-04 Tom Tromey <tromey@adacore.com>
* gdb.ada/enum_idx_packed.exp: Add tests.
* gdb.ada/enum_idx_packed/foo.adb: Add variables.
* gdb.ada/enum_idx_packed/pck.adb: Add functions.
* gdb.ada/enum_idx_packed/pck.ads: Add types, function
declarations.
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r-- | gdb/ada-lang.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 941b35f..93d8225 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -2139,6 +2139,35 @@ decode_constrained_packed_array_type (struct type *type) return constrained_packed_array_type (shadow_type, &bits); } +/* Helper function for decode_constrained_packed_array. Set the field + bitsize on a series of packed arrays. Returns the number of + elements in TYPE. */ + +static LONGEST +recursively_update_array_bitsize (struct type *type) +{ + gdb_assert (type->code () == TYPE_CODE_ARRAY); + + LONGEST low, high; + if (get_discrete_bounds (type->index_type (), &low, &high) < 0 + || low > high) + return 0; + LONGEST our_len = high - low + 1; + + struct type *elt_type = TYPE_TARGET_TYPE (type); + if (elt_type->code () == TYPE_CODE_ARRAY) + { + LONGEST elt_len = recursively_update_array_bitsize (elt_type); + LONGEST elt_bitsize = elt_len * TYPE_FIELD_BITSIZE (elt_type, 0); + TYPE_FIELD_BITSIZE (type, 0) = elt_bitsize; + + TYPE_LENGTH (type) = ((our_len * elt_bitsize + HOST_CHAR_BIT - 1) + / HOST_CHAR_BIT); + } + + return our_len; +} + /* Given that ARR is a struct value *indicating a GNAT constrained packed array, returns a simple array that denotes that array. Its type is a standard GDB array type except that the BITSIZEs of the array @@ -2168,6 +2197,18 @@ decode_constrained_packed_array (struct value *arr) return NULL; } + /* Decoding the packed array type could not correctly set the field + bitsizes for any dimension except the innermost, because the + bounds may be variable and were not passed to that function. So, + we further resolve the array bounds here and then update the + sizes. */ + const gdb_byte *valaddr = value_contents_for_printing (arr); + CORE_ADDR address = value_address (arr); + gdb::array_view<const gdb_byte> view + = gdb::make_array_view (valaddr, TYPE_LENGTH (type)); + type = resolve_dynamic_type (type, view, address); + recursively_update_array_bitsize (type); + if (type_byte_order (value_type (arr)) == BFD_ENDIAN_BIG && ada_is_modular_type (value_type (arr))) { |