aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2025-01-10 10:32:00 +0100
committerTom de Vries <tdevries@suse.de>2025-01-10 10:32:00 +0100
commit84067a55fcbb15f903c7298adc3a708c6a431e12 (patch)
treea5de032bc112d1a89702e886c07880bfd0deabd6 /gdb/testsuite
parent52cb36ccb92e252eb37d4dcde8adbf34aab1caaa (diff)
downloadgdb-84067a55fcbb15f903c7298adc3a708c6a431e12.zip
gdb-84067a55fcbb15f903c7298adc3a708c6a431e12.tar.gz
gdb-84067a55fcbb15f903c7298adc3a708c6a431e12.tar.bz2
[gdb/tdep] Fix gdb.cp/non-trivial-retval.exp on riscv64-linux
With test-case gdb.cp/non-trivial-retval.exp on riscv64-linux, I ran into: ... (gdb) finish^M Run till exit from #0 f1 (i1=i1@entry=23, i2=i2@entry=100) \ at non-trivial-retval.cc:34^M main () at non-trivial-retval.cc:163^M 163 B b = f2 (i1, i2);^M Value returned is $6 = {a = -5856}^M (gdb) FAIL: $exp: finish from f1 ... where "Value returned is $6 = {a = 123}" is expected. The problem is that gdb thinks that the return value is in $a0: ... $ gdb -q -batch non-trivial-retval \ -ex "b f1" \ -ex run \ -ex "set debug riscv infcall on" \ -ex finish Breakpoint 1 at 0x80a: file non-trivial-retval.cc, line 34. [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/riscv64-linux-gnu/libthread_db.so.1". Breakpoint 1, f1 (i1=i1@entry=23, i2=i2@entry=100) at non-trivial-retval.cc:34 34 { [riscv-infcall] riscv_return_value: \ [R] type: 'A', length: 0x4, alignment: 0x4, register a0 [riscv-infcall] riscv_return_value: \ [R] type: 'A', length: 0x4, alignment: 0x4, register a0 [riscv-infcall] riscv_return_value: \ [R] type: 'A', length: 0x4, alignment: 0x4, register a0 main () at non-trivial-retval.cc:163 163 B b = f2 (i1, i2); Value returned is $1 = {a = -3568} ... while $a0 actually contains a pointer to the returned value 123: ... (gdb) p /x $a0 $3 = 0x3ffffff210 (gdb) p *((unsigned int *)$a0) $5 = 123 ... The returned type is: ... class A { public: A () {} A (A &obj); int a; }; ... which is a C++ aggregate with a nontrivial (because it's user-defined) copy constructor: According to the ABI [1], indeed this is returned by reference: ... Values are returned in the same manner as a first named argument of the same type would be passed. If such an argument would have been passed by reference, the caller allocates memory for the return value, and passes the address as an implicit first parameter. ... Aggregates larger than 2×XLEN bits are passed by reference and are replaced in the argument list with the address, as are C++ aggregates with nontrivial copy constructors, destructors, or vtables. ... Fix this in riscv_call_arg_scalar_int by checking for language_pass_by_reference ().trivially_copy_constructible. The vtable case is explictly mentioned in the ABI, but AFAIU already covered by the nontrivial copy constructor case. The nontrivial destructor case is also not supported, but the testsuite doesn't seem to trigger this. Fix this by: - extending the test-case to cover this scenario, and - fixing it in riscv_call_arg_scalar_int by checking for language_pass_by_reference ().trivially_destructible. Tested on riscv64-linux. PR tdep/32152 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32152 Approved-By: Andrew Burgess <aburgess@redhat.com> [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/gdb.cp/non-trivial-retval.cc19
-rw-r--r--gdb/testsuite/gdb.cp/non-trivial-retval.exp6
2 files changed, 25 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.cp/non-trivial-retval.cc b/gdb/testsuite/gdb.cp/non-trivial-retval.cc
index 4bba0f1..4e81251 100644
--- a/gdb/testsuite/gdb.cp/non-trivial-retval.cc
+++ b/gdb/testsuite/gdb.cp/non-trivial-retval.cc
@@ -142,6 +142,24 @@ f4 (int i1, int i2)
return e;
}
+class F
+{
+public:
+ ~F () {}
+
+ int f;
+};
+
+F
+f5 (int i1, int i2)
+{
+ F f;
+
+ f.f = i1 + i2;
+
+ return f;
+}
+
/* We place a breakpoint on the call to this function. */
void
@@ -164,6 +182,7 @@ main (void)
B1 b1 = f22 (i1, i2);
C c = f3 (i1, i2);
E e = f4 (i1, i2);
+ F f = f5 (i1, i2);
return 0;
}
diff --git a/gdb/testsuite/gdb.cp/non-trivial-retval.exp b/gdb/testsuite/gdb.cp/non-trivial-retval.exp
index 89035e1..6c9f7e1 100644
--- a/gdb/testsuite/gdb.cp/non-trivial-retval.exp
+++ b/gdb/testsuite/gdb.cp/non-trivial-retval.exp
@@ -42,12 +42,14 @@ gdb_test "p f2 (i1, i2)" ".* = {b = 123}"
gdb_test "p f22 (i1, i2)" ".* = {b1 = 123}"
gdb_test "p f3 (i1, i2)" ".* = {.* c = 123}"
gdb_test "p f4 (i1, i2)" ".* = {.* e = 123}"
+gdb_test "p f5 (i1, i2)" ".* = {f = 123}"
gdb_breakpoint "f1"
gdb_breakpoint "f2"
gdb_breakpoint "f22"
gdb_breakpoint "f3"
gdb_breakpoint "f4"
+gdb_breakpoint "f5"
gdb_continue_to_breakpoint "Break in f1"
gdb_test "finish" " = {a = 123}" \
@@ -68,3 +70,7 @@ gdb_test "finish" " = {.* c = 123}" \
gdb_continue_to_breakpoint "Break in f4"
gdb_test "finish" " = {.* e = 123}" \
"finish from f4"
+
+gdb_continue_to_breakpoint "Break in f5"
+gdb_test "finish" " = {f = 123}" \
+ "finish from f5"