summaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@gnat.com>2013-05-20 09:45:11 +0000
committerJoel Brobecker <brobecker@gnat.com>2013-05-20 09:45:11 +0000
commit452e29236ed5bf99404ecd3531df85a058a12ff5 (patch)
tree10acf1bea5524a81e0dfc921c8e6c61b2271bf78 /gdb/dwarf2read.c
parent4072a8adda6f9c894beee03ed64a2b3c9b8c182b (diff)
downloadgdb-452e29236ed5bf99404ecd3531df85a058a12ff5.tar.gz
[dwarf] Mark all functions as prototyped except C functions.
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.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index a17cd9db037..036ccfe15d2 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -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