diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-04-05 13:50:19 +0100 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-04-11 23:37:45 +0100 |
commit | 9f0272f8548164b024ff9fd151686b2b904a5d59 (patch) | |
tree | 0d23c89b0c26d8f0259e823c218e7ed6931fc5cd /gdb/ChangeLog | |
parent | 02cf60c7a42710ee0364698c436b6ca5e771374b (diff) | |
download | gdb-9f0272f8548164b024ff9fd151686b2b904a5d59.zip gdb-9f0272f8548164b024ff9fd151686b2b904a5d59.tar.gz gdb-9f0272f8548164b024ff9fd151686b2b904a5d59.tar.bz2 |
gdb/riscv: Handle empty C++ structs during argument passing
This commit resolves a large number of failures in the test script
gdb.base/infcall-nested-structs.exp which were caused by GDB (for
RISC-V) incorrectly handling empty C++ structures when preparing
arguments for a dummy call, or collecting a return value.
The issue is further complicated in that there was a bug in GCC, such
that in some cases GCC would generate incorrect code when passing a
small structure that contained empty sub-structures. This was fixed
in GCC trunk on 5-March-2019, so in order to see the best results with
this patch you'll need a recent version of GCC.
Anything that used to work should continue to work after this patch,
regardless of GCC version being used.
The fix in this commit is that GDB now pays more attention to the
offset of fields within a structure when preparing arguments as in C++
an empty structure has a non-zero size, this is an example:
struct s1 { struct s2 { } empty; int f; };
We previously assumed that 'f' was at offset 0 inside type 's1',
however this is not the case in C++ as 's2' has size 1, and with
alignment 'f' is likely at some even bigger offset inside 's1'.
gdb/ChangeLog:
* riscv-tdep.c (riscv_call_arg_complex_float): Fix offset of first
component to 0.
(riscv_struct_info::riscv_struct_info): Initialise m_offsets
member.
(riscv_struct_info::analyse): New implementation using new
analyse_inner member function.
(riscv_struct_info::field_offset): New member function.
(riscv_struct_info::m_offsets): New member variable.
(riscv_struct_info::analyse_inner): New private member function,
takes the old implementation of riscv_struct_info::analyse but
extended to track field offsets.
(riscv_call_arg_struct): Update the struct folding special cases
to handle cases where empty C++ structs, which are non-zero
length, are found.
(riscv_arg_location): Initialise the length of each location, a
non-zero length now indicates the location is in use.
(riscv_push_dummy_call): Allow for the first location having a
non-zero offset when setting up arguments.
(riscv_return_value): Likewise, but for return values.
Diffstat (limited to 'gdb/ChangeLog')
-rw-r--r-- | gdb/ChangeLog | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7428ed9..0be7538 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2019-04-11 Andrew Burgess <andrew.burgess@embecosm.com> + + * riscv-tdep.c (riscv_call_arg_complex_float): Fix offset of first + component to 0. + (riscv_struct_info::riscv_struct_info): Initialise m_offsets + member. + (riscv_struct_info::analyse): New implementation using new + analyse_inner member function. + (riscv_struct_info::field_offset): New member function. + (riscv_struct_info::m_offsets): New member variable. + (riscv_struct_info::analyse_inner): New private member function, + takes the old implementation of riscv_struct_info::analyse but + extended to track field offsets. + (riscv_call_arg_struct): Update the struct folding special cases + to handle cases where empty C++ structs, which are non-zero + length, are found. + (riscv_arg_location): Initialise the length of each location, a + non-zero length now indicates the location is in use. + (riscv_push_dummy_call): Allow for the first location having a + non-zero offset when setting up arguments. + (riscv_return_value): Likewise, but for return values. + 2019-04-11 Tom Tromey <tromey@adacore.com> * utils.c (internal_vproblem): Make "msg" const. |