public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [pushed/Ada] Improved support for pointers to dynamic arrays
@ 2014-09-10 13:39 Joel Brobecker
  2014-09-10 13:39 ` [pushed/Ada 2/4] Ada subscripting of pointer to array with dynamic bounds Joel Brobecker
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Joel Brobecker @ 2014-09-10 13:39 UTC (permalink / raw)
  To: gdb-patches

Hello,

This patch series improves support for pointers to dynamic arrays,
when the dynamic properties are expressed using pure DWARF constructs
as opposed to GNAT encodings.

Tested on x86_64-linux and pushhed.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pushed/Ada 1/4] print PTR.all where PTR is an Ada thin pointer
  2014-09-10 13:39 [pushed/Ada] Improved support for pointers to dynamic arrays Joel Brobecker
                   ` (2 preceding siblings ...)
  2014-09-10 13:39 ` [pushed/Ada 3/4] Ada: Print bounds/length of pointer to array with dynamic bounds Joel Brobecker
@ 2014-09-10 13:39 ` Joel Brobecker
  3 siblings, 0 replies; 5+ messages in thread
From: Joel Brobecker @ 2014-09-10 13:39 UTC (permalink / raw)
  To: gdb-patches

Consider the following declaration:

   type Array_Type is array (Natural range <>) of Integer;
   type Array_Ptr is access all Array_Type;
   for Array_Ptr'Size use 64;
   Three_Ptr : Array_Ptr := new Array_Type'(1 => 1, 2 => 2, 3 => 3);

This creates a pointer to an array where the bounds are stored
in a memory region just before the array itself (aka a "thin pointer").
In DWARF, this is described as a the usual pointer type to an array
whose subrange has dynamic values for its bounds:

    <1><25>: Abbrev Number: 4 (DW_TAG_array_type)
       <26>   DW_AT_name        : foo__array_type
    [...]
    <2><3b>: Abbrev Number: 5 (DW_TAG_subrange_type)
       [...]
       <40>   DW_AT_lower_bound : 5 byte block: 97 38 1c 94 4
              (DW_OP_push_object_address; DW_OP_lit8; DW_OP_minus;
               DW_OP_deref_size: 4)
       <46>   DW_AT_upper_bound : 5 byte block: 97 34 1c 94 4
              (DW_OP_push_object_address; DW_OP_lit4; DW_OP_minus;
               DW_OP_deref_size: 4)

GDB is currently printing the value of the array incorrectly:

    (gdb) p foo.three_ptr.all
    $1 = (26629472 => 1, 2,
    value.c:819: internal-error: value_contents_bits_eq: [...]

The dereferencing (".all" operator) is done by calling ada_value_ind,
which itself calls value_ind. It first produces a new value where
the bounds of the array were correctly resolved to their actual value,
but then calls readjust_indirect_value_type which replaces the resolved
type by the original type.

The problem starts when ada_value_print does not take this situation
into account, and starts using the type of the resulting value, which
has unresolved array bounds, instead of using the value's enclosing
type.

After fixing this issue, the debugger now correctly prints:

    (gdb) p foo.three_ptr.all
    $1 = (1, 2, 3)

gdb/ChangeLog:

        * ada-valprint.c (ada_value_print): Use VAL's enclosing type
        instead of VAL's type.

gdb/testsuite/ChangeLog:

        * gdb.dwarf2/dynarr-ptr.c: New file.
        * gdb.dwarf2/dynarr-ptr.exp: New file.
---
 gdb/ChangeLog                           |   5 ++
 gdb/ada-valprint.c                      |   2 +-
 gdb/testsuite/ChangeLog                 |   5 ++
 gdb/testsuite/gdb.dwarf2/dynarr-ptr.c   |  30 +++++++
 gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp | 153 ++++++++++++++++++++++++++++++++
 5 files changed, 194 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.dwarf2/dynarr-ptr.c
 create mode 100644 gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2d20b1c..82e3622 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2014-09-10  Joel Brobecker  <brobecker@adacore.com>
 
+	* ada-valprint.c (ada_value_print): Use VAL's enclosing type
+	instead of VAL's type.
+
+2014-09-10  Joel Brobecker  <brobecker@adacore.com>
+
 	* amd64-linux-nat.c: Add <sys/uio.h> #include.
 
 2014-09-09  Doug Evans  <xdje42@gmail.com>
diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c
index ae07cc2..ade0a65 100644
--- a/gdb/ada-valprint.c
+++ b/gdb/ada-valprint.c
@@ -1171,7 +1171,7 @@ ada_value_print (struct value *val0, struct ui_file *stream,
 {
   struct value *val = ada_to_fixed_value (val0);
   CORE_ADDR address = value_address (val);
-  struct type *type = ada_check_typedef (value_type (val));
+  struct type *type = ada_check_typedef (value_enclosing_type (val));
   struct value_print_options opts;
 
   /* If it is a pointer, indicate what it points to.  */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 37fe6a1..e7bba77 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-09-10  Joel Brobecker  <brobecker@adacore.com>
+
+	* gdb.dwarf2/dynarr-ptr.c: New file.
+	* gdb.dwarf2/dynarr-ptr.exp: New file.
+
 2014-09-09  Maciej W. Rozycki  <macro@codesourcery.com>
 
 	* gdb.base/watchpoint-solib.exp: Increase the timeout by a factor
diff --git a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.c b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.c
new file mode 100644
index 0000000..2bdf254
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.c
@@ -0,0 +1,30 @@
+/* Copyright 2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int table_1_data[] = {1, 3, 1, 2, 3};
+int *table_1_ptr = &table_1_data[2];
+
+int table_2_data[] = {2, 6, 5, 8, 13, 21, 34};
+int *table_2_ptr = &table_2_data[2];
+
+int
+main (void)
+{
+  *table_1_ptr = 2;
+  *table_2_ptr = 3;
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
new file mode 100644
index 0000000..501f129
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
@@ -0,0 +1,153 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0
+}
+
+standard_testfile dynarr-ptr.c dynarr-ptr-dw.S
+
+# We need to know the size of integer and address types in order
+# to write some of the debugging info we'd like to generate.
+#
+# For that, we ask GDB by debugging our dynarr-ptr.c program.
+# Any program would do, but since we already have dynarr-ptr.c
+# specifically for this testcase, might as well use that.
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    untested ${testfile}.exp
+    return -1
+}
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+    cu {} {
+ 	DW_TAG_compile_unit {
+                {DW_AT_language @DW_LANG_Ada95}
+                {DW_AT_name     foo.adb}
+                {DW_AT_comp_dir /tmp}
+        } {
+            declare_labels integer_label array_label array_ptr_label \
+                array_typedef_label
+            set ptr_size [get_sizeof "void *" 96]
+
+            integer_label: DW_TAG_base_type {
+                {DW_AT_byte_size 4 DW_FORM_sdata}
+                {DW_AT_encoding  @DW_ATE_signed}
+                {DW_AT_name      integer}
+            }
+
+	    array_label: DW_TAG_array_type {
+		{DW_AT_name foo__array_type}
+		{DW_AT_type :$integer_label}
+                {external 1 flag}
+	    } {
+		DW_TAG_subrange_type {
+		    {DW_AT_type        :$integer_label}
+                    {DW_AT_lower_bound {
+                        DW_OP_push_object_address
+                        DW_OP_lit8
+                        DW_OP_minus
+                        DW_OP_deref_size 4
+                    } SPECIAL_expr}
+                    {DW_AT_upper_bound {
+                        DW_OP_push_object_address
+                        DW_OP_lit4
+                        DW_OP_minus
+                        DW_OP_deref_size 4
+                    } SPECIAL_expr}
+		}
+	    }
+            array_ptr_label: DW_TAG_pointer_type {
+                {DW_AT_byte_size :$ptr_size }
+                {DW_AT_type :$array_label}
+            }
+            array_typedef_label: DW_TAG_typedef {
+                {DW_AT_name "foo__array_ptr"}
+                {DW_AT_type :$array_ptr_label}
+            }
+            DW_TAG_variable {
+                {DW_AT_name foo__three_ptr}
+                {DW_AT_type :$array_ptr_label}
+                {DW_AT_location {
+                    DW_OP_addr table_1_ptr
+                } SPECIAL_expr}
+                {external 1 flag}
+            }
+            DW_TAG_variable {
+                {DW_AT_name foo__three_ptr_tdef}
+                {DW_AT_type :$array_typedef_label}
+                {DW_AT_location {
+                    DW_OP_addr table_1_ptr
+                } SPECIAL_expr}
+                {external 1 flag}
+            }
+            DW_TAG_variable {
+                {DW_AT_name foo__five_ptr}
+                {DW_AT_type :$array_ptr_label}
+                {DW_AT_location {
+                    DW_OP_addr table_2_ptr
+                } SPECIAL_expr}
+                {external 1 flag}
+            }
+            DW_TAG_variable {
+                {DW_AT_name foo__five_ptr_tdef}
+                {DW_AT_type :$array_typedef_label}
+                {DW_AT_location {
+                    DW_OP_addr table_2_ptr
+                } SPECIAL_expr}
+                {external 1 flag}
+            }
+	}
+    }
+}
+
+# Now that we've generated the DWARF debugging info, rebuild our
+# program using our debug info instead of the info generated by
+# the compiler.
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} \
+	  [list $srcfile $asm_file] {nodebug}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_test_no_output "set language ada"
+
+# foo.three_ptr.all
+
+gdb_test "print foo.three_ptr.all" \
+         " = \\(1, 2, 3\\)"
+
+# foo.three_ptr_tdef.all
+
+gdb_test "print foo.three_ptr_tdef.all" \
+         " = \\(1, 2, 3\\)"
+
+# foo.five_ptr.all
+
+gdb_test "print foo.five_ptr.all" \
+         " = \\(2 => 5, 8, 13, 21, 34\\)"
+
+# foo.five_ptr_tdef.all
+
+gdb_test "print foo.five_ptr_tdef.all" \
+         " = \\(2 => 5, 8, 13, 21, 34\\)"
-- 
1.9.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pushed/Ada 3/4] Ada: Print bounds/length of pointer to array with dynamic bounds
  2014-09-10 13:39 [pushed/Ada] Improved support for pointers to dynamic arrays Joel Brobecker
  2014-09-10 13:39 ` [pushed/Ada 2/4] Ada subscripting of pointer to array with dynamic bounds Joel Brobecker
  2014-09-10 13:39 ` [pushed/Ada 4/4] dynarr-ptr.exp: Add ptype tests Joel Brobecker
@ 2014-09-10 13:39 ` Joel Brobecker
  2014-09-10 13:39 ` [pushed/Ada 1/4] print PTR.all where PTR is an Ada thin pointer Joel Brobecker
  3 siblings, 0 replies; 5+ messages in thread
From: Joel Brobecker @ 2014-09-10 13:39 UTC (permalink / raw)
  To: gdb-patches

Trying to print the bounds or the length of a pointer to an array
whose bounds are dynamic results in the following error:

    (gdb) p foo.three_ptr.all'first
    Location address is not set.
    (gdb) p foo.three_ptr.all'length
    Location address is not set.

This is because, after having dereferenced our array pointer, we
use the type of the resulting array value, instead of the enclosing
type.  The former is the original type where the bounds are unresolved,
whereas we need to get the actual array bounds.

Similarly, trying to apply those attributes to the array pointer
directly (without explicitly dereferencing it with the '.all'
operator) yields the same kind of error:

    (gdb) p foo.three_ptr'first
    Location address is not set.
    (gdb) p foo.three_ptr'length
    Location address is not set.

This is caused by the fact that the dereference was done implicitly
in this case, and perform at the type level only, which is not
sufficient in order to resolve the array type.

This patch fixes both issues, thus allowing us to get the expected output:

    (gdb) p foo.three_ptr.all'first
    $1 = 1
    (gdb) p foo.three_ptr.all'length
    $2 = 3
    (gdb) p foo.three_ptr'first
    $3 = 1
    (gdb) p foo.three_ptr'length
    $4 = 3

gdb/ChangeLog:

        * ada-lang.c (ada_array_bound): If ARR is a TYPE_CODE_PTR,
        dereference it first.  Use value_enclosing_type instead of
        value_type.
        (ada_array_length): Likewise.

gdb/testsuite/ChangeLog:

        * gdb.dwarf2/dynarr-ptr.exp: Add 'first, 'last and 'length tests.
---
 gdb/ChangeLog                           |  7 ++++
 gdb/ada-lang.c                          | 12 +++++-
 gdb/testsuite/ChangeLog                 |  4 ++
 gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp | 72 +++++++++++++++++++++++++++++++++
 4 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 67f631d..4601ae7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
 2014-09-10  Joel Brobecker  <brobecker@adacore.com>
 
+	* ada-lang.c (ada_array_bound): If ARR is a TYPE_CODE_PTR,
+	dereference it first.  Use value_enclosing_type instead of
+	value_type.
+	(ada_array_length): Likewise.
+
+2014-09-10  Joel Brobecker  <brobecker@adacore.com>
+
 	* ada-lang.c (ada_value_ptr_subscript): Remove parameter "type".
 	Adjust function implementation and documentation accordingly.
 	(ada_evaluate_subexp) <OP_FUNCALL>: Only assign "type" if
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 4c6d039..c7e50e2 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -2942,7 +2942,11 @@ ada_array_bound_from_type (struct type *arr_type, int n, int which)
 static LONGEST
 ada_array_bound (struct value *arr, int n, int which)
 {
-  struct type *arr_type = value_type (arr);
+  struct type *arr_type;
+
+  if (TYPE_CODE (check_typedef (value_type (arr))) == TYPE_CODE_PTR)
+    arr = value_ind (arr);
+  arr_type = value_enclosing_type (arr);
 
   if (ada_is_constrained_packed_array_type (arr_type))
     return ada_array_bound (decode_constrained_packed_array (arr), n, which);
@@ -2961,7 +2965,11 @@ ada_array_bound (struct value *arr, int n, int which)
 static LONGEST
 ada_array_length (struct value *arr, int n)
 {
-  struct type *arr_type = ada_check_typedef (value_type (arr));
+  struct type *arr_type;
+
+  if (TYPE_CODE (check_typedef (value_type (arr))) == TYPE_CODE_PTR)
+    arr = value_ind (arr);
+  arr_type = value_enclosing_type (arr);
 
   if (ada_is_constrained_packed_array_type (arr_type))
     return ada_array_length (decode_constrained_packed_array (arr), n);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index ebb7e6a..66b50a9 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2014-09-10  Joel Brobecker  <brobecker@adacore.com>
 
+	* gdb.dwarf2/dynarr-ptr.exp: Add 'first, 'last and 'length tests.
+
+2014-09-10  Joel Brobecker  <brobecker@adacore.com>
+
 	* gdb.dwarf2/dynarr-ptr.exp: Add subscripting tests.
 
 2014-09-10  Joel Brobecker  <brobecker@adacore.com>
diff --git a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
index 1df5e3c..696c765 100644
--- a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
+++ b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
@@ -146,6 +146,15 @@ gdb_test "print foo.three_ptr.all(2)" \
 gdb_test "print foo.three_ptr.all(3)" \
          " = 3"
 
+gdb_test "print foo.three_ptr.all'first" \
+         " = 1"
+
+gdb_test "print foo.three_ptr.all'last" \
+         " = 3"
+
+gdb_test "print foo.three_ptr.all'length" \
+         " = 3"
+
 # foo.three_ptr
 
 gdb_test "print foo.three_ptr(1)" \
@@ -157,6 +166,15 @@ gdb_test "print foo.three_ptr(2)" \
 gdb_test "print foo.three_ptr(3)" \
          " = 3"
 
+gdb_test "print foo.three_ptr'first" \
+         " = 1"
+
+gdb_test "print foo.three_ptr'last" \
+         " = 3"
+
+gdb_test "print foo.three_ptr'length" \
+         " = 3"
+
 # foo.three_ptr_tdef.all
 
 gdb_test "print foo.three_ptr_tdef.all" \
@@ -171,6 +189,15 @@ gdb_test "print foo.three_ptr_tdef.all(2)" \
 gdb_test "print foo.three_ptr_tdef.all(3)" \
          " = 3"
 
+gdb_test "print foo.three_ptr_tdef.all'first" \
+         " = 1"
+
+gdb_test "print foo.three_ptr_tdef.all'last" \
+         " = 3"
+
+gdb_test "print foo.three_ptr_tdef.all'length" \
+         " = 3"
+
 # foo.three_ptr_tdef
 
 gdb_test "print foo.three_ptr_tdef(1)" \
@@ -182,6 +209,15 @@ gdb_test "print foo.three_ptr_tdef(2)" \
 gdb_test "print foo.three_ptr_tdef(3)" \
          " = 3"
 
+gdb_test "print foo.three_ptr_tdef'first" \
+         " = 1"
+
+gdb_test "print foo.three_ptr_tdef'last" \
+         " = 3"
+
+gdb_test "print foo.three_ptr_tdef'length" \
+         " = 3"
+
 # foo.five_ptr.all
 
 gdb_test "print foo.five_ptr.all" \
@@ -202,6 +238,15 @@ gdb_test "print foo.five_ptr.all(5)" \
 gdb_test "print foo.five_ptr.all(6)" \
          " = 34"
 
+gdb_test "print foo.five_ptr.all'first" \
+         " = 2"
+
+gdb_test "print foo.five_ptr.all'last" \
+         " = 6"
+
+gdb_test "print foo.five_ptr.all'length" \
+         " = 5"
+
 # foo.five_ptr
 
 gdb_test "print foo.five_ptr(2)" \
@@ -219,6 +264,15 @@ gdb_test "print foo.five_ptr(5)" \
 gdb_test "print foo.five_ptr(6)" \
          " = 34"
 
+gdb_test "print foo.five_ptr'first" \
+         " = 2"
+
+gdb_test "print foo.five_ptr'last" \
+         " = 6"
+
+gdb_test "print foo.five_ptr'length" \
+         " = 5"
+
 # foo.five_ptr_tdef.all
 
 gdb_test "print foo.five_ptr_tdef.all" \
@@ -239,6 +293,15 @@ gdb_test "print foo.five_ptr_tdef.all(5)" \
 gdb_test "print foo.five_ptr_tdef.all(6)" \
          " = 34"
 
+gdb_test "print foo.five_ptr_tdef.all'first" \
+         " = 2"
+
+gdb_test "print foo.five_ptr_tdef.all'last" \
+         " = 6"
+
+gdb_test "print foo.five_ptr_tdef.all'length" \
+         " = 5"
+
 # foo.five_ptr_tdef
 
 gdb_test "print foo.five_ptr_tdef(2)" \
@@ -255,3 +318,12 @@ gdb_test "print foo.five_ptr_tdef(5)" \
 
 gdb_test "print foo.five_ptr_tdef(6)" \
          " = 34"
+
+gdb_test "print foo.five_ptr_tdef'first" \
+         " = 2"
+
+gdb_test "print foo.five_ptr_tdef'last" \
+         " = 6"
+
+gdb_test "print foo.five_ptr_tdef'length" \
+         " = 5"
-- 
1.9.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pushed/Ada 4/4] dynarr-ptr.exp: Add ptype tests.
  2014-09-10 13:39 [pushed/Ada] Improved support for pointers to dynamic arrays Joel Brobecker
  2014-09-10 13:39 ` [pushed/Ada 2/4] Ada subscripting of pointer to array with dynamic bounds Joel Brobecker
@ 2014-09-10 13:39 ` Joel Brobecker
  2014-09-10 13:39 ` [pushed/Ada 3/4] Ada: Print bounds/length of pointer to array with dynamic bounds Joel Brobecker
  2014-09-10 13:39 ` [pushed/Ada 1/4] print PTR.all where PTR is an Ada thin pointer Joel Brobecker
  3 siblings, 0 replies; 5+ messages in thread
From: Joel Brobecker @ 2014-09-10 13:39 UTC (permalink / raw)
  To: gdb-patches

This patch adds a number of "ptype" tests to gdb.dwarf2/dynarr-ptr.exp.

gdb/testsuite/ChangeLog:

        * gdb.dwarf2/dynarr-ptr.exp: Add a few ptype tests.
---
 gdb/testsuite/ChangeLog                 |  4 ++++
 gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp | 24 ++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 66b50a9..fd932a5 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2014-09-10  Joel Brobecker  <brobecker@adacore.com>
 
+	* gdb.dwarf2/dynarr-ptr.exp: Add a few ptype tests.
+
+2014-09-10  Joel Brobecker  <brobecker@adacore.com>
+
 	* gdb.dwarf2/dynarr-ptr.exp: Add 'first, 'last and 'length tests.
 
 2014-09-10  Joel Brobecker  <brobecker@adacore.com>
diff --git a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
index 696c765..3730837 100644
--- a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
+++ b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
@@ -155,6 +155,9 @@ gdb_test "print foo.three_ptr.all'last" \
 gdb_test "print foo.three_ptr.all'length" \
          " = 3"
 
+gdb_test "ptype foo.three_ptr.all" \
+         " = array \\(<>\\) of integer"
+
 # foo.three_ptr
 
 gdb_test "print foo.three_ptr(1)" \
@@ -175,6 +178,9 @@ gdb_test "print foo.three_ptr'last" \
 gdb_test "print foo.three_ptr'length" \
          " = 3"
 
+gdb_test "ptype foo.three_ptr" \
+         " = access array \\(<>\\) of integer"
+
 # foo.three_ptr_tdef.all
 
 gdb_test "print foo.three_ptr_tdef.all" \
@@ -198,6 +204,9 @@ gdb_test "print foo.three_ptr_tdef.all'last" \
 gdb_test "print foo.three_ptr_tdef.all'length" \
          " = 3"
 
+gdb_test "ptype foo.three_ptr_tdef.all" \
+         " = array \\(<>\\) of integer"
+
 # foo.three_ptr_tdef
 
 gdb_test "print foo.three_ptr_tdef(1)" \
@@ -218,6 +227,9 @@ gdb_test "print foo.three_ptr_tdef'last" \
 gdb_test "print foo.three_ptr_tdef'length" \
          " = 3"
 
+gdb_test "ptype foo.three_ptr_tdef" \
+         " = access array \\(<>\\) of integer"
+
 # foo.five_ptr.all
 
 gdb_test "print foo.five_ptr.all" \
@@ -247,6 +259,9 @@ gdb_test "print foo.five_ptr.all'last" \
 gdb_test "print foo.five_ptr.all'length" \
          " = 5"
 
+gdb_test "ptype foo.five_ptr.all" \
+         " = array \\(<>\\) of integer"
+
 # foo.five_ptr
 
 gdb_test "print foo.five_ptr(2)" \
@@ -273,6 +288,9 @@ gdb_test "print foo.five_ptr'last" \
 gdb_test "print foo.five_ptr'length" \
          " = 5"
 
+gdb_test "ptype foo.five_ptr" \
+         " = access array \\(<>\\) of integer"
+
 # foo.five_ptr_tdef.all
 
 gdb_test "print foo.five_ptr_tdef.all" \
@@ -302,6 +320,9 @@ gdb_test "print foo.five_ptr_tdef.all'last" \
 gdb_test "print foo.five_ptr_tdef.all'length" \
          " = 5"
 
+gdb_test "ptype foo.five_ptr_tdef.all" \
+         " = array \\(<>\\) of integer"
+
 # foo.five_ptr_tdef
 
 gdb_test "print foo.five_ptr_tdef(2)" \
@@ -327,3 +348,6 @@ gdb_test "print foo.five_ptr_tdef'last" \
 
 gdb_test "print foo.five_ptr_tdef'length" \
          " = 5"
+
+gdb_test "ptype foo.five_ptr_tdef" \
+         " = access array \\(<>\\) of integer"
-- 
1.9.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pushed/Ada 2/4] Ada subscripting of pointer to array with dynamic bounds
  2014-09-10 13:39 [pushed/Ada] Improved support for pointers to dynamic arrays Joel Brobecker
@ 2014-09-10 13:39 ` Joel Brobecker
  2014-09-10 13:39 ` [pushed/Ada 4/4] dynarr-ptr.exp: Add ptype tests Joel Brobecker
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Joel Brobecker @ 2014-09-10 13:39 UTC (permalink / raw)
  To: gdb-patches

Consider a pointer to an array which dynamic bounds, described in
DWARF as follow:

        <1><25>: Abbrev Number: 4 (DW_TAG_array_type)
           <26>   DW_AT_name        : foo__array_type
        [...]
        <2><3b>: Abbrev Number: 5 (DW_TAG_subrange_type)
           [...]
           <40>   DW_AT_lower_bound : 5 byte block: 97 38 1c 94 4
                  (DW_OP_push_object_address; DW_OP_lit8; DW_OP_minus;
                   DW_OP_deref_size: 4)
           <46>   DW_AT_upper_bound : 5 byte block: 97 34 1c 94 4
                  (DW_OP_push_object_address; DW_OP_lit4; DW_OP_minus;
                   DW_OP_deref_size: 4)

GDB is now able to correctly print the entire array, but not one
element of the array. Eg:

    (gdb) p foo.three_ptr.all
    $1 = (1, 2, 3)
    (gdb) p foo.three_ptr.all(1)
    Cannot access memory at address 0xfffffffff4123a0c

The problem occurs because we are missing a dynamic resolution of
the variable's array type when subscripting the array. What the current
code does is "fix"-ing the array type using the GNAT encodings, but
that operation ignores any of the array's dynamic properties.

This patch fixes the issue by using ada_value_ind to dereference
the array pointer, which takes care of the array type resolution.
It also continues to "fix" arrays described using GNAT encodings,
so backwards compatibility is preserved.

gdb/ChangeLog:

        * ada-lang.c (ada_value_ptr_subscript): Remove parameter "type".
        Adjust function implementation and documentation accordingly.
        (ada_evaluate_subexp) <OP_FUNCALL>: Only assign "type" if
        NOSIDE is EVAL_AVOID_SIDE_EFFECTS.
        Update call to ada_value_ptr_subscript.

gdb/testsuite/ChangeLog:

        * gdb.dwarf2/dynarr-ptr.exp: Add subscripting tests.
---
 gdb/ChangeLog                           |   8 +++
 gdb/ada-lang.c                          |  17 +++---
 gdb/testsuite/ChangeLog                 |   4 ++
 gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp | 104 ++++++++++++++++++++++++++++++++
 4 files changed, 125 insertions(+), 8 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 82e3622..67f631d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,13 @@
 2014-09-10  Joel Brobecker  <brobecker@adacore.com>
 
+	* ada-lang.c (ada_value_ptr_subscript): Remove parameter "type".
+	Adjust function implementation and documentation accordingly.
+	(ada_evaluate_subexp) <OP_FUNCALL>: Only assign "type" if
+	NOSIDE is EVAL_AVOID_SIDE_EFFECTS.
+	Update call to ada_value_ptr_subscript.
+
+2014-09-10  Joel Brobecker  <brobecker@adacore.com>
+
 	* ada-valprint.c (ada_value_print): Use VAL's enclosing type
 	instead of VAL's type.
 
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 28999c7..4c6d039 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -2715,15 +2715,16 @@ ada_value_subscript (struct value *arr, int arity, struct value **ind)
   return elt;
 }
 
-/* Assuming ARR is a pointer to a standard GDB array of type TYPE, the
-   value of the element of *ARR at the ARITY indices given in
-   IND.  Does not read the entire array into memory.  */
+/* Assuming ARR is a pointer to a GDB array, the value of the element
+   of *ARR at the ARITY indices given in IND.
+   Does not read the entire array into memory.  */
 
 static struct value *
-ada_value_ptr_subscript (struct value *arr, struct type *type, int arity,
-                         struct value **ind)
+ada_value_ptr_subscript (struct value *arr, int arity, struct value **ind)
 {
   int k;
+  struct type *type
+    = check_typedef (value_enclosing_type (ada_value_ind (arr)));
 
   for (k = 0; k < arity; k += 1)
     {
@@ -10323,9 +10324,9 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
                           (ada_coerce_to_simple_array (argvec[0]),
                            nargs, argvec + 1));
         case TYPE_CODE_PTR:     /* Pointer to array */
-          type = to_fixed_array_type (TYPE_TARGET_TYPE (type), NULL, 1);
           if (noside == EVAL_AVOID_SIDE_EFFECTS)
             {
+	      type = to_fixed_array_type (TYPE_TARGET_TYPE (type), NULL, 1);
               type = ada_array_element_type (type, nargs);
               if (type == NULL)
                 error (_("element type of array unknown"));
@@ -10333,8 +10334,8 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
                 return value_zero (ada_aligned_type (type), lval_memory);
             }
           return
-            unwrap_value (ada_value_ptr_subscript (argvec[0], type,
-                                                   nargs, argvec + 1));
+            unwrap_value (ada_value_ptr_subscript (argvec[0],
+						   nargs, argvec + 1));
 
         default:
           error (_("Attempt to index or call something other than an "
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index e7bba77..ebb7e6a 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2014-09-10  Joel Brobecker  <brobecker@adacore.com>
 
+	* gdb.dwarf2/dynarr-ptr.exp: Add subscripting tests.
+
+2014-09-10  Joel Brobecker  <brobecker@adacore.com>
+
 	* gdb.dwarf2/dynarr-ptr.c: New file.
 	* gdb.dwarf2/dynarr-ptr.exp: New file.
 
diff --git a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
index 501f129..1df5e3c 100644
--- a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
+++ b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
@@ -137,17 +137,121 @@ gdb_test_no_output "set language ada"
 gdb_test "print foo.three_ptr.all" \
          " = \\(1, 2, 3\\)"
 
+gdb_test "print foo.three_ptr.all(1)" \
+         " = 1"
+
+gdb_test "print foo.three_ptr.all(2)" \
+         " = 2"
+
+gdb_test "print foo.three_ptr.all(3)" \
+         " = 3"
+
+# foo.three_ptr
+
+gdb_test "print foo.three_ptr(1)" \
+         " = 1"
+
+gdb_test "print foo.three_ptr(2)" \
+         " = 2"
+
+gdb_test "print foo.three_ptr(3)" \
+         " = 3"
+
 # foo.three_ptr_tdef.all
 
 gdb_test "print foo.three_ptr_tdef.all" \
          " = \\(1, 2, 3\\)"
 
+gdb_test "print foo.three_ptr_tdef.all(1)" \
+         " = 1"
+
+gdb_test "print foo.three_ptr_tdef.all(2)" \
+         " = 2"
+
+gdb_test "print foo.three_ptr_tdef.all(3)" \
+         " = 3"
+
+# foo.three_ptr_tdef
+
+gdb_test "print foo.three_ptr_tdef(1)" \
+         " = 1"
+
+gdb_test "print foo.three_ptr_tdef(2)" \
+         " = 2"
+
+gdb_test "print foo.three_ptr_tdef(3)" \
+         " = 3"
+
 # foo.five_ptr.all
 
 gdb_test "print foo.five_ptr.all" \
          " = \\(2 => 5, 8, 13, 21, 34\\)"
 
+gdb_test "print foo.five_ptr.all(2)" \
+         " = 5"
+
+gdb_test "print foo.five_ptr.all(3)" \
+         " = 8"
+
+gdb_test "print foo.five_ptr.all(4)" \
+         " = 13"
+
+gdb_test "print foo.five_ptr.all(5)" \
+         " = 21"
+
+gdb_test "print foo.five_ptr.all(6)" \
+         " = 34"
+
+# foo.five_ptr
+
+gdb_test "print foo.five_ptr(2)" \
+         " = 5"
+
+gdb_test "print foo.five_ptr(3)" \
+         " = 8"
+
+gdb_test "print foo.five_ptr(4)" \
+         " = 13"
+
+gdb_test "print foo.five_ptr(5)" \
+         " = 21"
+
+gdb_test "print foo.five_ptr(6)" \
+         " = 34"
+
 # foo.five_ptr_tdef.all
 
 gdb_test "print foo.five_ptr_tdef.all" \
          " = \\(2 => 5, 8, 13, 21, 34\\)"
+
+gdb_test "print foo.five_ptr_tdef.all(2)" \
+         " = 5"
+
+gdb_test "print foo.five_ptr_tdef.all(3)" \
+         " = 8"
+
+gdb_test "print foo.five_ptr_tdef.all(4)" \
+         " = 13"
+
+gdb_test "print foo.five_ptr_tdef.all(5)" \
+         " = 21"
+
+gdb_test "print foo.five_ptr_tdef.all(6)" \
+         " = 34"
+
+# foo.five_ptr_tdef
+
+gdb_test "print foo.five_ptr_tdef(2)" \
+         " = 5"
+
+gdb_test "print foo.five_ptr_tdef(3)" \
+         " = 8"
+
+gdb_test "print foo.five_ptr_tdef(4)" \
+         " = 13"
+
+gdb_test "print foo.five_ptr_tdef(5)" \
+         " = 21"
+
+gdb_test "print foo.five_ptr_tdef(6)" \
+         " = 34"
-- 
1.9.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-09-10 13:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-10 13:39 [pushed/Ada] Improved support for pointers to dynamic arrays Joel Brobecker
2014-09-10 13:39 ` [pushed/Ada 2/4] Ada subscripting of pointer to array with dynamic bounds Joel Brobecker
2014-09-10 13:39 ` [pushed/Ada 4/4] dynarr-ptr.exp: Add ptype tests Joel Brobecker
2014-09-10 13:39 ` [pushed/Ada 3/4] Ada: Print bounds/length of pointer to array with dynamic bounds Joel Brobecker
2014-09-10 13:39 ` [pushed/Ada 1/4] print PTR.all where PTR is an Ada thin pointer Joel Brobecker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).