summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@adacore.com>2018-01-01 22:53:55 -0500
committerJoel Brobecker <brobecker@adacore.com>2018-01-01 22:53:55 -0500
commit9fe561ab7fc5ee3a06061dae6909cd61b49435df (patch)
treef7be8d4ae10087198dc0aced0562d3ef251ad69a
parenta405673cc5b56c260de4e1202cead709d1a4f24c (diff)
downloadbinutils-gdb-9fe561ab7fc5ee3a06061dae6909cd61b49435df.tar.gz
[gdb/Ada] slices of arrays with dynamic strides
Consider the following Ada code: procedure Nested (L, U : Integer) is subtype Small_Type is Integer range L .. U; type Record_Type (I : Small_Type := L) is record S : String (1 .. I); end record; type Array_Type is array (Integer range <>) of Record_Type; A1 : Array_Type := (1 => (I => 0, S => <>), 2 => (I => 1, S => "A"), 3 => (I => 2, S => "AB")); procedure Discard (R : Record_Type) is begin null; end Discard; begin Discard (A1 (1)); -- STOP end; Trying to print a slice of that array currently yields: (gdb) p a1(1..3) $1 = ((i => 0, s => ""), (i => 0, s => ""), (i => 0, s => "")) We expected instead: (gdb) p a1(1..3) $1 = ((i => 0, s => ""), (i => 1, s => "A"), (i => 2, s => "AB")) This is because the functions we use in ada-lang.c to create the type of the array slice (ada_value_slice and ada_value_slice_from_ptr) was not taking into account the stride of the array. This patch fixes this. gdb/ChangeLog: * ada-lang.c (ada_value_slice_from_ptr): Take array stride into account when creating the array type of the slice. (ada_value_slice): Likewise. gdb/testsuite/ChangeLog: * gdb.ada/dyn_stride.exp: Add slice test. Note that, with the current use of ada_value_slice, the enhancement to handle dynamic array strides seems unnecessary, because I do not see how an array with a dynamic stride can be referenced by either by reference or pointer. Since references are coerced to array pointers, in both cases, the slice is performed by ada_value_slice_from_ptr. But ada_value_slice is enhanced nonetheless, in the spirit of making the code more robust, in case we missed something, and also as similar as possible with its from_ptr counterpart. tested on x86_64-linux.
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/ada-lang.c12
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.ada/dyn_stride.exp3
4 files changed, 21 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2c25683c428..1ab2a892352 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
2018-01-02 Joel Brobecker <brobecker@adacore.com>
+ * ada-lang.c (ada_value_slice_from_ptr): Take array stride into
+ account when creating the array type of the slice.
+ (ada_value_slice): Likewise.
+
+2018-01-02 Joel Brobecker <brobecker@adacore.com>
+
* gdbtypes.h (enum dynamic_prop_node_kind) <DYN_PROP_BYTE_STRIDE>:
New enum value.
(create_array_type_with_stride): Add byte_stride_prop parameter.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 208dda42ded..851e69ac4ba 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -2910,8 +2910,10 @@ ada_value_slice_from_ptr (struct value *array_ptr, struct type *type,
struct type *base_index_type = TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (type0));
struct type *index_type
= create_static_range_type (NULL, base_index_type, low, high);
- struct type *slice_type =
- create_array_type (NULL, TYPE_TARGET_TYPE (type0), index_type);
+ struct type *slice_type = create_array_type_with_stride
+ (NULL, TYPE_TARGET_TYPE (type0), index_type,
+ get_dyn_prop (DYN_PROP_BYTE_STRIDE, type0),
+ TYPE_FIELD_BITSIZE (type0, 0));
int base_low = ada_discrete_type_low_bound (TYPE_INDEX_TYPE (type0));
LONGEST base_low_pos, low_pos;
CORE_ADDR base;
@@ -2938,8 +2940,10 @@ ada_value_slice (struct value *array, int low, int high)
struct type *base_index_type = TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (type));
struct type *index_type
= create_static_range_type (NULL, TYPE_INDEX_TYPE (type), low, high);
- struct type *slice_type =
- create_array_type (NULL, TYPE_TARGET_TYPE (type), index_type);
+ struct type *slice_type = create_array_type_with_stride
+ (NULL, TYPE_TARGET_TYPE (type), index_type,
+ get_dyn_prop (DYN_PROP_BYTE_STRIDE, type),
+ TYPE_FIELD_BITSIZE (type, 0));
LONGEST low_pos, high_pos;
if (!discrete_position (base_index_type, low, &low_pos)
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 06f0f4735f7..9ef8dd1be5f 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2018-01-02 Joel Brobecker <brobecker@adacore.com>
+ * gdb.ada/dyn_stride.exp: Add slice test.
+
+2018-01-02 Joel Brobecker <brobecker@adacore.com>
+
* gdb.ada/dyn_stride: New testcase.
2017-12-27 Stafford Horne <shorne@gmail.com>
diff --git a/gdb/testsuite/gdb.ada/dyn_stride.exp b/gdb/testsuite/gdb.ada/dyn_stride.exp
index 33723d46c19..0267ca192bf 100644
--- a/gdb/testsuite/gdb.ada/dyn_stride.exp
+++ b/gdb/testsuite/gdb.ada/dyn_stride.exp
@@ -36,3 +36,6 @@ gdb_test "print A1(2)" \
gdb_test "print A1(3)" \
"\\(i => 2, s => \"AB\"\\)"
+
+gdb_test "print A1(1..3)" \
+ "\\(\\(i => 0, s => \"\"\\), \\(i => 1, s => \"A\"\\), \\(i => 2, s => \"AB\"\\)\\)"