From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11977 invoked by alias); 15 May 2013 13:20:04 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 11925 invoked by uid 89); 15 May 2013 13:20:04 -0000 X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL,BAYES_00,KHOP_THREADED,RCVD_IN_HOSTKARMA_NO,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.1 Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 15 May 2013 13:20:02 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 861432E668; Wed, 15 May 2013 09:20:00 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id KCmhh1j+Sbqf; Wed, 15 May 2013 09:20:00 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 02A062E0D6; Wed, 15 May 2013 09:20:00 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 17340C2A7D; Wed, 15 May 2013 17:19:48 +0400 (RET) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [RFA/dwarf 2/2] Mark all functions as prototyped except C functions. Date: Wed, 15 May 2013 13:20:00 -0000 Message-Id: <1368623983-10625-3-git-send-email-brobecker@adacore.com> In-Reply-To: <1368623983-10625-1-git-send-email-brobecker@adacore.com> References: <87txm6dhhm.fsf@fleche.redhat.com> <1368623983-10625-1-git-send-email-brobecker@adacore.com> X-SW-Source: 2013-05/txt/msg00524.txt.bz2 Hello, This is the part of the patch series that inverts the logic determining whether or not a function should be marked as prototyped. I took this opportunity to factorize a bit the code setting the PROTOTYPED flag. Although the gain is very marginal, I think it helps because a large block now becomes very small, thus showing its intent a little more clearly. Below is the adjusted problem description which will be part of the commit RH. ---- This makes sure that the types of the arguments are taken into account when performing an inferior function call to a non-C 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. The DWARF standard implies that the DW_AT_prototyped is only meaningful for C. So there is no reason to expect this flag to be set for any other language. We assume, instead, that functions are always prototyped for all non-C languages... gdb/ChangeLog: * dwarf2read.c (prototyped_function_p): New function. (read_subroutine_type): Use it. gdb/testsuite/ChangeLog: * gdb.ada/float_param: New testcase. Tested on x86_64-linux. No regression. OK to commit? -- Joel --- gdb/dwarf2read.c | 41 +++++++++++++++++++-------- 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, 161 insertions(+), 12 deletions(-) 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 a17cd9d..be6644b 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -12600,6 +12600,34 @@ 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 to C. So assume that non-C functions are + always prototyped. */ + if (cu->language != language_c) + 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 +12655,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 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 . + +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 . + +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 . + +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 . + +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