[dwarf] Mark all functions as prototyped except C functions.
authorJoel Brobecker <brobecker@gnat.com>
Mon, 20 May 2013 09:45:13 +0000 (09:45 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Mon, 20 May 2013 09:45:13 +0000 (09:45 +0000)
This makes sure that the types of the arguments are taken into account
when performing an inferior function call to a non-C (or C-like)
function.  In particular, this makes sure that the arguments are
appropriatly converted to the correct type.

For instance, on x86_64-linux, with the following Ada 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.

This patch fixes the problem by setting the PROTOTYPE flag
for all functions of any language except C and Objective C.

gdb/ChangeLog:

        * dwarf2read.c (prototyped_function_p): New function.
        (read_subroutine_type): Use it.

gdb/testsuite/ChangeLog:

        * gdb.ada/float_param: New testcase.

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

index e536b1529ae2289663561dbf03385d4a89d4902e..ba4c83e8dc2494c0642b14a908d289eb7dd9c9c0 100644 (file)
@@ -1,3 +1,8 @@
+2013-05-20  Joel Brobecker  <brobecker@adacore.com>
+
+       * dwarf2read.c (prototyped_function_p): New function.
+       (read_subroutine_type): Use it.
+
 2013-05-20  Joel Brobecker  <brobecker@adacore.com>
 
        * rs6000-aix-tdep.c: De-indent some example code provided
index a17cd9db037e84d97a78cd2de255cd2313329dfe..036ccfe15d29fd67c2e94ed89b83196eefeec8b7 100644 (file)
@@ -12600,6 +12600,38 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
+/* Assuming that DIE corresponds to a function, returns nonzero
+   if the function is prototyped.  */
+
+static int
+prototyped_function_p (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_prototyped, cu);
+  if (attr && (DW_UNSND (attr) != 0))
+    return 1;
+
+  /* The DWARF standard implies that the DW_AT_prototyped attribute
+     is only meaninful for C, but the concept also extends to other
+     languages that allow unprototyped functions (Eg: Objective C).
+     For all other languages, assume that functions are always
+     prototyped.  */
+  if (cu->language != language_c
+      && cu->language != language_objc
+      && cu->language != language_opencl)
+    return 1;
+
+  /* RealView does not emit DW_AT_prototyped.  We can not distinguish
+     prototyped and unprototyped functions; default to prototyped,
+     since that is more common in modern code (and RealView warns
+     about unprototyped functions).  */
+  if (producer_is_realview (cu->producer))
+    return 1;
+
+  return 0;
+}
+
 /* Handle DIES due to C code like:
 
    struct foo
@@ -12627,18 +12659,7 @@ 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.  */
-  attr = dwarf2_attr (die, DW_AT_prototyped, cu);
-  if ((attr && (DW_UNSND (attr) != 0))
-      || cu->language == language_cplus
-      || cu->language == language_java
-      || cu->language == language_pascal)
-    TYPE_PROTOTYPED (ftype) = 1;
-  else if (producer_is_realview (cu->producer))
-    /* RealView does not emit DW_AT_prototyped.  We can not
-       distinguish prototyped and unprototyped functions; default to
-       prototyped, since that is more common in modern code (and
-       RealView warns about unprototyped functions).  */
+  if (prototyped_function_p (die, cu))
     TYPE_PROTOTYPED (ftype) = 1;
 
   /* Store the calling convention in the type if it's available in
index cb940e141c534fd6aef1c950fd13566053964d13..f944fc4e2e6d636f9a14b753e9fcc915b4274722 100644 (file)
@@ -1,3 +1,7 @@
+2013-05-20  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdb.ada/float_param: New testcase.
+
 2013-05-17  Doug Evans  <dje@google.com>
 
        * gdb.base/maint.exp: Update test for "maint check-psymtabs".
diff --git a/gdb/testsuite/gdb.ada/float_param.exp b/gdb/testsuite/gdb.ada/float_param.exp
new file mode 100644 (file)
index 0000000..f0a7eac
--- /dev/null
@@ -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 (file)
index 0000000..2b08681
--- /dev/null
@@ -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 (file)
index 0000000..18967e4
--- /dev/null
@@ -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 (file)
index 0000000..093a32d
--- /dev/null
@@ -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;
This page took 0.051716 seconds and 4 git commands to generate.