Fix array stride bug

Investigation of using the Python API with an Ada program showed that
an array of dynamic types was not being handled properly.  I tracked
this down to an oddity of how array strides are handled.

In gdb, an array stride can be attached to the range type, via the
range_bounds object.  However, the stride can also be put into the
array's first field.  From create_range_type_with_stride:

  else if (bit_stride > 0)
    TYPE_FIELD_BITSIZE (result_type, 0) = bit_stride;

It's hard to be sure why this is done, but I would guess a combination
of historical reasons plus a desire (mentioned in a comment somewhere)
to avoid modifying the range type.

This patch fixes the problem by changing type::bit_stride to
understand this convention.  It also fixes one spot that reproduces
this logic.

Regression tested on x86-64 Fedora 32.
This commit is contained in:
Tom Tromey 2021-06-18 13:08:33 -06:00
parent 05a1dd47cc
commit cc9d6997a5
3 changed files with 20 additions and 7 deletions

View File

@ -1280,13 +1280,7 @@ update_static_array_size (struct type *type)
int stride;
struct type *element_type;
/* If the array itself doesn't provide a stride value then take
whatever stride the range provides. Don't update BIT_STRIDE as
we don't want to place the stride value from the range into this
arrays bit size field. */
stride = TYPE_FIELD_BITSIZE (type, 0);
if (stride == 0)
stride = range_type->bit_stride ();
stride = type->bit_stride ();
if (!get_discrete_bounds (range_type, &low_bound, &high_bound))
low_bound = high_bound = 0;

View File

@ -1029,6 +1029,8 @@ struct type
ULONGEST bit_stride () const
{
if (this->code () == TYPE_CODE_ARRAY && this->field (0).bitsize != 0)
return this->field (0).bitsize;
return this->bounds ()->bit_stride ();
}

View File

@ -14,6 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
load_lib "ada.exp"
load_lib "gdb-python.exp"
if { [skip_ada_tests] } { return -1 }
@ -49,4 +50,20 @@ foreach_with_prefix scenario {all minimal} {
gdb_test "print objects(2 .. 2)" \
[string_to_regexp " = (2 => $v2)"] \
"print second array slice"
# This is only supported for the DWARF encoding.
if {$scenario == "minimal" && ![skip_python_tests]} {
gdb_test_no_output \
"python o = gdb.parse_and_eval('objects')" \
"fetch value for python"
gdb_test "python print(o)" \
[string_to_regexp "($v1, $v2)"] \
"python print array"
gdb_test "python print(o\[1\])" \
[string_to_regexp "$v1"] \
"python print first array element"
gdb_test "python print(o\[2\])" \
[string_to_regexp "$v2"] \
"python print second array element"
}
}