This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 0/8] Fix inferior call for C++ pass-by-reference arguments
- From: Tankut Baris Aktemur <tankut dot baris dot aktemur at intel dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 23 Apr 2019 16:31:46 +0200
- Subject: [PATCH 0/8] Fix inferior call for C++ pass-by-reference arguments
Dear All,
This is a set of patches to fix GDB's conformance to C++ ABI when
invoking functions that have call-by-value arguments of aggregate
types that should be implicitly passed by reference.
To give some background information first, suppose we have a class 'K'
and a function 'cbv' that has a call-by-value parameter of type 'K'.
class K {
public:
K (const K &other) { ... }
~K (void) { ... }
...
};
int
cbv (K k)
{
... use k ...
}
int
main (void)
{
K q1;
...
cbv (q1);
...
}
When making a function call such as 'cbv(q1)', the caller needs to
create a (temporary) copy of the argument 'q1', say 'q2', and pass
'q2' to 'cbv' as the argument. After the function call returns, the
caller can discard 'q2'. However, because the type 'K' has a
user-defined constructor and destructor, the caller cannot simply copy
the contents of 'q1' to 'q2'; it has to initialize 'q2' via the copy
constructor. Similarly, 'q2' has to be destroyed by invoking the
user-defined destructor. For this reason, according to the C++ ABI,
the caller first allocates a space for 'q2', initializes it using the
copy constructor, and then passes the *address* of 'q2' to 'cbv'. The
caller uses the same address to destruct 'q2' after the function call
is complete. Although 'k' is declared as a call-by-value parameter,
it is implicitly *pass-by-reference*.
Had the type 'K' not have a user-defined copy constructor or a
destructor, the caller could have cloned 'q1' to 'q2' by a
straightforward memory copying operation. Such types are trivially
copyable. In that case, 'K' would be a *pass-by-value* type.
Present-day GDB has problems regarding pass-by-reference arguments
when making inferior calls. In particular:
- Relatively new DWARF attributes are not used for inferring whether
a type is pass-by-reference or not. This leads to incorrect
deductions and, in return, crashing inferior calls.
- For a pass-by-reference argument, a copy of the argument is not
made; the address of the argument itself is passed to the callee.
Hence, no copy-constructor call or a destructor call takes place,
as well.
The proposed patch aims to fix these problems. Tested on the X86_64
architecture with GCC 7.4.0 and 8.2.0. ChangeLog entries will be
included in the patch when/if the patch is accepted.
Best regards.
Tankut Baris Aktemur (8):
gdb: recognize new DWARF attributes: defaulted, deleted, calling conv.
infcall, c++: allow more info to be computed for pass-by-reference
values
infcall, c++: collect more pass-by-reference information
infcall: refactor 'call_function_by_hand_dummy'
infcall: move assertions in 'call_function_by_hand_dummy' to an
earlier spot
infcall: remove unused parameter in 'value_arg_coerce'
infcall: handle pass-by-reference arguments appropriately
testsuite, cp: increase the coverage of testing pass-by-ref arguments
gdb/arch-utils.c | 2 +-
gdb/cp-abi.c | 6 +-
gdb/cp-abi.h | 10 +-
gdb/dwarf2read.c | 20 +
gdb/gdbtypes.c | 7 +
gdb/gdbtypes.h | 19 +-
gdb/gnu-v3-abi.c | 268 +-
gdb/infcall.c | 213 +-
gdb/language.c | 27 +-
gdb/language.h | 55 +-
gdb/testsuite/gdb.cp/pass-by-ref-2.cc | 179 +
gdb/testsuite/gdb.cp/pass-by-ref-2.exp | 85 +
gdb/testsuite/gdb.cp/pass-by-ref.cc | 7368 +++++++++++++++++++++++-
gdb/testsuite/gdb.cp/pass-by-ref.exp | 412 +-
gdb/tic6x-tdep.c | 2 +-
15 files changed, 8514 insertions(+), 159 deletions(-)
create mode 100644 gdb/testsuite/gdb.cp/pass-by-ref-2.cc
create mode 100644 gdb/testsuite/gdb.cp/pass-by-ref-2.exp
--
2.21.0