[RFA/commit] DWARF: Mark all Ada functions as prototyped.

Joel Brobecker
2013-05-13T10:17:11Z

Hello,

This makes sure that the types of the arguments are taken into account
when performing an inferior function call, and in particular
appropriatly converted to the correct type.

For instance, on x86_64-linux, with the following code:

procedure Set_Float (F : Float) is
begin
Global_Float := F;
end Set_Float;

The following sequence shows that Float arguments are incorrectly
passed (Ada's Float type is the equivalent of type "float" in C):

(gdb) call set_float (2.0)
(gdb) print global_float
$1 = 0.0

Putting a breakpoint inside set_float to inspect the value of
register xmm0 gives the first hint of the problem:

(gdb) p $xmm0
$2 = (v4_float => (0 => 0.0, 2.0, 0.0, 0.0),
v2_double => (0 => 2.0, 0.0),
[...]

It shows that the argument was passed as a double.

The code responsible for doing appropriate type conversions
for the arguments (value_arg_coerce) found that our function
was not prototyped, and thus could not use typing information
for the arguments. Instead, it defaulted to the value of "set
coerce-float-to-double", which by default is true, to determine
the argument type.

All functions in Ada are always prototyped, so there is no reason
to wait for the DW_AT_prototyped flag to be set. This patch adjusts
the dwarf2 function reader to follow what is already being done for
C++, Pascal, etc, and makes sure that all Ada functions are always
marked as prototyped.

gdb/ChangeLog:

* dwarf2read.c (read_subroutine_type): Mark all Ada functions
as prototyped.

gdb/testsuite/ChangeLog:

* gdb.ada/float_param: New testcase.

Tested on x86_64-linux, no regression. Fixes:

FAIL: gdb.ada/float_param.exp: print global_float

It seems relatively straightforward, but I will wait a couple of days
or approval before checking in...

Thank you,
--
Joel

---
gdb/dwarf2read.c | 3 +-
gdb/testsuite/gdb.ada/float_param.exp | 43 +++++++++++++++++++++++++++++
gdb/testsuite/gdb.ada/float_param/foo.adb | 23 +++++++++++++++
gdb/testsuite/gdb.ada/float_param/pck.adb | 35 +++++++++++++++++++++++
gdb/testsuite/gdb.ada/float_param/pck.ads | 31 +++++++++++++++++++++
5 files changed, 134 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.ada/float_param.exp
create mode 100644 gdb/testsuite/gdb.ada/float_param/foo.adb
create mode 100644 gdb/testsuite/gdb.ada/float_param/pck.adb
create mode 100644 gdb/testsuite/gdb.ada/float_param/pck.ads

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 2a5acf0..803e3ff 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -12626,9 +12626,10 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)

ftype = lookup_function_type (type);

- /* All functions in C++, Pascal and Java have prototypes. */
+ /* All functions in Ada, C++, Pascal and Java have prototypes. */
attr = dwarf2_attr (die, DW_AT_prototyped, cu);
if ((attr && (DW_UNSND (attr) != 0))
+ || cu->language == language_ada
|| cu->language == language_cplus
|| cu->language == language_java
|| cu->language == language_pascal)
diff --git a/gdb/testsuite/gdb.ada/float_param.exp b/gdb/testsuite/gdb.ada/float_param.exp
new file mode 100644
index 0000000..f0a7eac
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/float_param.exp
@@ -0,0 +1,43 @@
+# Copyright 2013 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 }
+
+standard_ada_testfile foo
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+ return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "START" ${testdir}/foo.adb]
+runto "foo.adb:$bp_location"
+
+gdb_test_no_output "call set_float(2.0)"
+gdb_test "print global_float" \
+ " = 2\\.0"
+
+gdb_test_no_output "call set_double(1, 3.0)"
+gdb_test "print global_double" \
+ " = 3\\.0"
+
+gdb_test_no_output "call set_long_double(1, global_small_struct, 4.0)"
+gdb_test "print global_long_double" \
+ " = 4\\.0"
+
+
diff --git a/gdb/testsuite/gdb.ada/float_param/foo.adb b/gdb/testsuite/gdb.ada/float_param/foo.adb
new file mode 100644
index 0000000..2b08681
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/float_param/foo.adb
@@ -0,0 +1,23 @@
+-- Copyright 2013 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
+begin
+ Set_Float (1.0); -- START
+ Set_Double (1, 1.0);
+ Set_Long_Double (1, (I => 2), 1.0);
+end Foo;
diff --git a/gdb/testsuite/gdb.ada/float_param/pck.adb b/gdb/testsuite/gdb.ada/float_param/pck.adb
new file mode 100644
index 0000000..18967e4
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/float_param/pck.adb
@@ -0,0 +1,35 @@
+-- Copyright 2013 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
+
+ procedure Set_Float (F : Float) is
+ begin
+ Global_Float := F;
+ end Set_Float;
+
+ procedure Set_Double (Dummy : Integer; D : Long_Float) is
+ begin
+ Global_Double := D;
+ end Set_Double;
+
+ procedure Set_Long_Double (Dummy : Integer;
+ DS : Small_Struct;
+ LD : Long_Long_Float) is
+ begin
+ Global_Long_Double := LD;
+ end Set_Long_Double;
+
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/float_param/pck.ads b/gdb/testsuite/gdb.ada/float_param/pck.ads
new file mode 100644
index 0000000..093a32d
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/float_param/pck.ads
@@ -0,0 +1,31 @@
+-- Copyright 2013 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 Pck is
+ Global_Float : Float := 0.0;
+ Global_Double : Long_Float := 0.0;
+ Global_Long_Double : Long_Long_Float := 0.0;
+
+ type Small_Struct is record
+ I : Integer;
+ end record;
+ Global_Small_Struct : Small_Struct := (I => 0);
+
+ procedure Set_Float (F : Float);
+ procedure Set_Double (Dummy : Integer; D : Long_Float);
+ procedure Set_Long_Double (Dummy : Integer;
+ DS: Small_Struct;
+ LD : Long_Long_Float);
+end Pck;
--
1.7.10.4