[Ada] Handle reference to array descriptors
authorJoel Brobecker <brobecker@gnat.com>
Wed, 29 Feb 2012 19:33:02 +0000 (19:33 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Wed, 29 Feb 2012 19:33:02 +0000 (19:33 +0000)
This patch is to help handle aliased array variables, such as:

   type Bounded is array (Integer range <>) of Integer;
   function New_Bounded (Low, High : Integer) return Bounded;
   BT : aliased Bounded := New_Bounded (Low => 1, High => 3);

In that case, the compiler describes variable "BT" as a reference
to a thin pointer, and GDB is unable to print its value:

    (gdb) p bt
    $1 =

The problems starts when ada_value_print deconstructs the struct
value into contents and address in order to call val_print. It
turns out in this case that "bt" is not an lval. In the debug
information, this variable's location is described as:

        .uleb128 0xd    # (DIE (0xe0) DW_TAG_variable)
        .ascii "bt\0"   # DW_AT_name
        [...]
        .byte   0x6     # DW_AT_location
        .byte   0x91    # DW_OP_fbreg
        .sleb128 -56
        .byte   0x6     # DW_OP_deref
        .byte   0x23    # DW_OP_plus_uconst
        .uleb128 0x8
        .byte   0x9f    # DW_OP_stack_value

So, when ada_value_print passes the bt's (value) address, it passes
in effect a meaningless address. The problem continues shortly after
when ada_val_print_1 re-creates the value from the contents and address.
The value has become an lval_memory, with a null address.

As a result, we trigger a memory error later on, while trying to
read the array bounds in order to transform our value into a simple
array.

To avoid the problem entirely, the fix is to coerce references before
transforming array descriptors into simple arrays.

gdb/ChangeLog:

        * ada-valprint.c (ada_val_print_1): If our value is a reference
        to an array descriptor, dereference it before converting it
        to a simple array.

gdb/testsuite/ChangeLog:

        * gdb.ada/aliased_array: New testcase.

gdb/ChangeLog
gdb/ada-valprint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/aliased_array.exp [new file with mode: 0644]
gdb/testsuite/gdb.ada/aliased_array/foo.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/aliased_array/pck.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/aliased_array/pck.ads [new file with mode: 0644]

index 064efa2efe30ce9651929bd4da80f06761bc6c8f..d09ed947df1c718ec940ef29d4157ddb66f5c889 100644 (file)
@@ -1,3 +1,9 @@
+2012-02-29  Joel Brobecker  <brobecker@adacore.com>
+
+       * ada-valprint.c (ada_val_print_1): If our value is a reference
+       to an array descriptor, dereference it before converting it
+       to a simple array.
+
 2012-02-29  Joel Brobecker  <brobecker@adacore.com>
 
        * ada-lang.c (ada_to_fixed_value): Call unwrap_value before
index f43f3e3be5e405ee461fe21b8129981735245084..5cb2f98c760b99e3d4d2b5244b4d5864dd594837 100644 (file)
@@ -689,6 +689,10 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr,
       struct value *val;
 
       val = value_from_contents_and_address (type, valaddr + offset, address);
+      /* If this is a reference, coerce it now.  This helps taking care
+        of the case where ADDRESS is meaningless because original_value
+        was not an lval.  */
+      val = coerce_ref (val);
       if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)  /* array access type.  */
        val = ada_coerce_to_simple_array_ptr (val);
       else
index 8a144bc9b89f7377cdb80e362488968a87047c40..af77953a3d835191568f41b681ba4518deda1b50 100644 (file)
@@ -1,3 +1,7 @@
+2012-02-29  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdb.ada/aliased_array: New testcase.
+
 2012-02-29  Joel Brobecker  <brobecker@adacore.com>
 
        * gdb.ada/whatis_array_val: New testcase.
diff --git a/gdb/testsuite/gdb.ada/aliased_array.exp b/gdb/testsuite/gdb.ada/aliased_array.exp
new file mode 100644 (file)
index 0000000..9fe30df
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright 2012 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 "ada.exp"
+
+if { [skip_ada_tests] } { return -1 }
+
+set testdir "aliased_array"
+set testfile "${testdir}/foo"
+set srcfile ${srcdir}/${subdir}/${testfile}.adb
+set binfile ${objdir}/${subdir}/${testfile}
+
+file mkdir ${objdir}/${subdir}/${testdir}
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+    return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb]
+runto "foo.adb:$bp_location"
+
+gdb_test "print bt" " = \\(1, 2, 3\\)"
+
diff --git a/gdb/testsuite/gdb.ada/aliased_array/foo.adb b/gdb/testsuite/gdb.ada/aliased_array/foo.adb
new file mode 100644 (file)
index 0000000..28acc87
--- /dev/null
@@ -0,0 +1,22 @@
+--  Copyright 2012 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/>.
+
+with Pck; use Pck;
+procedure Foo is
+   BT : aliased Bounded := New_Bounded (Low => 1, High => 3);
+begin
+   Do_Nothing (BT'Address); -- STOP
+end Foo;
+
diff --git a/gdb/testsuite/gdb.ada/aliased_array/pck.adb b/gdb/testsuite/gdb.ada/aliased_array/pck.adb
new file mode 100644 (file)
index 0000000..29de743
--- /dev/null
@@ -0,0 +1,30 @@
+--  Copyright 2012 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/>.
+
+package body Pck is
+   function New_Bounded (Low, High : Integer) return Bounded is
+      Result : Bounded (Low .. High);
+   begin
+      for J in Low .. High loop
+         Result (J) := J;
+      end loop;
+      return Result;
+   end New_Bounded;
+
+   procedure Do_Nothing (A : System.Address) is
+   begin
+      null;
+   end Do_Nothing;
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/aliased_array/pck.ads b/gdb/testsuite/gdb.ada/aliased_array/pck.ads
new file mode 100644 (file)
index 0000000..bfff520
--- /dev/null
@@ -0,0 +1,21 @@
+--  Copyright 2012 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/>.
+
+with System;
+package Pck is
+   type Bounded is array (Integer range <>) of Integer;
+   function New_Bounded (Low, High : Integer) return Bounded;
+   procedure Do_Nothing (A : System.Address);
+end Pck;