[gdb/Ada] slices of arrays with dynamic strides
authorJoel Brobecker <brobecker@adacore.com>
Tue, 2 Jan 2018 03:53:55 +0000 (22:53 -0500)
committerJoel Brobecker <brobecker@adacore.com>
Tue, 2 Jan 2018 03:53:55 +0000 (22:53 -0500)
    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.

gdb/ChangeLog
gdb/ada-lang.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/dyn_stride.exp

index 2c25683c4282556129a014e1e546bbeed6eb994d..1ab2a892352a5964cc5a839bd888b0fd8269f487 100644 (file)
@@ -1,3 +1,9 @@
+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>:
index 208dda42ded8d2e24e0e853ea05322a78b5128b8..851e69ac4bab465dcd5c0b1f4ed544c0e913c9c4 100644 (file)
@@ -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)
index 06f0f4735f7f81533d9112e1f0dfb0c4018758eb..9ef8dd1be5fb037a22cd808df55ae8579177be9a 100644 (file)
@@ -1,3 +1,7 @@
+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.
index 33723d46c193a02c6869623861f151087d673649..0267ca192bf169c6c8ec0ea5074d927de371747b 100644 (file)
@@ -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\"\\)\\)"