aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2021-06-18 13:08:33 -0600
committerTom Tromey <tromey@adacore.com>2021-07-16 08:23:47 -0600
commitcc9d6997a5b23d0c8e1960f6c0b5f5cdf456d4e9 (patch)
tree98b8274e28e753f9ba06b8c17975fabba46199ac
parent05a1dd47cc9b6fcc8ec112bd0b68b36567ccbb39 (diff)
downloadgdb-cc9d6997a5b23d0c8e1960f6c0b5f5cdf456d4e9.zip
gdb-cc9d6997a5b23d0c8e1960f6c0b5f5cdf456d4e9.tar.gz
gdb-cc9d6997a5b23d0c8e1960f6c0b5f5cdf456d4e9.tar.bz2
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.
-rw-r--r--gdb/gdbtypes.c8
-rw-r--r--gdb/gdbtypes.h2
-rw-r--r--gdb/testsuite/gdb.ada/array_of_variant.exp17
3 files changed, 20 insertions, 7 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index dbc82f0..1a26171 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -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;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 0cc00e7..d754f2f 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -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 ();
}
diff --git a/gdb/testsuite/gdb.ada/array_of_variant.exp b/gdb/testsuite/gdb.ada/array_of_variant.exp
index dfcbe75..d93ad47 100644
--- a/gdb/testsuite/gdb.ada/array_of_variant.exp
+++ b/gdb/testsuite/gdb.ada/array_of_variant.exp
@@ -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"
+ }
}