* [PATCH 1/4] gdb.base/nodebug.exp: Add long double testing
2026-07-14 22:06 [PATCH 0/4] gdb/testsuite: "long double" infcall tests Pedro Alves
@ 2026-07-14 22:06 ` Pedro Alves
2026-07-16 21:14 ` Andrew Burgess
2026-07-14 22:06 ` [PATCH 2/4] gdb.base/callfuncs.exp: Adjust for Windows Pedro Alves
` (3 subsequent siblings)
4 siblings, 1 reply; 15+ messages in thread
From: Pedro Alves @ 2026-07-14 22:06 UTC (permalink / raw)
To: gdb-patches
gdb.base/nodebug.exp is missing testing calling long double functions.
This commit adds such tests.
With a GDB that doesn't know that "long double" is 64-bit on
x86_64-pc-windows-msvc, we get:
FAIL: gdb.base/nodebug.exp: p (long double) mult_long_double(2.0L, 3.0L)
FAIL: gdb.base/nodebug.exp: p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)
FAIL: gdb.base/nodebug.exp: p ((long double (*) (long double, long double)) mult_long_double)(2, 3)
FAIL: gdb.base/nodebug.exp: p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)
Passes cleanly on:
- x86_64-pc-linux-gnu
- x86_64-w64-mingw32
- x86_64-pc-windows-msvc, with the "long double" fix
Change-Id: If9ee749187e1d30fedcba17ae12634f3bd90de2f
---
gdb/testsuite/gdb.base/nodebug.c | 13 +++++++++++++
gdb/testsuite/gdb.base/nodebug.exp | 6 ++++++
2 files changed, 19 insertions(+)
diff --git a/gdb/testsuite/gdb.base/nodebug.c b/gdb/testsuite/gdb.base/nodebug.c
index c7bc93991b8..275a9d6ff60 100644
--- a/gdb/testsuite/gdb.base/nodebug.c
+++ b/gdb/testsuite/gdb.base/nodebug.c
@@ -72,6 +72,12 @@ mult (double v1, double v2)
return v1 * v2;
}
+long double
+mult_long_double (long double v1, long double v2)
+{
+ return v1 * v2;
+}
+
double
mult_noproto (v1, v2)
double v1, v2;
@@ -79,6 +85,13 @@ mult_noproto (v1, v2)
return v1 * v2;
}
+long double
+mult_long_double_noproto (v1, v2)
+ long double v1, v2;
+{
+ return v1 * v2;
+}
+
uint8_t
add8 (uint8_t v1, uint8_t v2)
{
diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
index e4138a801da..1a16e86ed2c 100644
--- a/gdb/testsuite/gdb.base/nodebug.exp
+++ b/gdb/testsuite/gdb.base/nodebug.exp
@@ -78,6 +78,12 @@ proc test_call_promotion {} {
gdb_test "p ((double (*) ()) mult_noproto)(2.0f, 3.0f)" " = 6"
gdb_test "p ((double (*) ()) mult_noproto)(2.0, 3.0)" " = 6"
+ # Same, but for long double.
+ gdb_test "p (long double) mult_long_double(2.0L, 3.0L)" " = 6"
+ gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)" " = 6"
+ gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2, 3)" " = 6"
+ gdb_test "p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)" " = 6"
+
# Check that GDB promotes char->int correctly.
gdb_test "p /d (uint8) add8((uint8) 2, (uint8) 3)" " = 5"
gdb_test "p /d ((uint8 (*) (uint8, uint8)) add8)((uint8) 2, (uint8) 3)" " = 5"
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 1/4] gdb.base/nodebug.exp: Add long double testing
2026-07-14 22:06 ` [PATCH 1/4] gdb.base/nodebug.exp: Add long double testing Pedro Alves
@ 2026-07-16 21:14 ` Andrew Burgess
2026-07-17 13:59 ` Pedro Alves
0 siblings, 1 reply; 15+ messages in thread
From: Andrew Burgess @ 2026-07-16 21:14 UTC (permalink / raw)
To: Pedro Alves, gdb-patches
Pedro Alves <pedro@palves.net> writes:
> gdb.base/nodebug.exp is missing testing calling long double functions.
> This commit adds such tests.
>
> With a GDB that doesn't know that "long double" is 64-bit on
> x86_64-pc-windows-msvc, we get:
>
> FAIL: gdb.base/nodebug.exp: p (long double) mult_long_double(2.0L, 3.0L)
> FAIL: gdb.base/nodebug.exp: p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)
> FAIL: gdb.base/nodebug.exp: p ((long double (*) (long double, long double)) mult_long_double)(2, 3)
> FAIL: gdb.base/nodebug.exp: p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)
>
> Passes cleanly on:
>
> - x86_64-pc-linux-gnu
> - x86_64-w64-mingw32
> - x86_64-pc-windows-msvc, with the "long double" fix
>
> Change-Id: If9ee749187e1d30fedcba17ae12634f3bd90de2f
> ---
> gdb/testsuite/gdb.base/nodebug.c | 13 +++++++++++++
> gdb/testsuite/gdb.base/nodebug.exp | 6 ++++++
> 2 files changed, 19 insertions(+)
>
> diff --git a/gdb/testsuite/gdb.base/nodebug.c b/gdb/testsuite/gdb.base/nodebug.c
> index c7bc93991b8..275a9d6ff60 100644
> --- a/gdb/testsuite/gdb.base/nodebug.c
> +++ b/gdb/testsuite/gdb.base/nodebug.c
> @@ -72,6 +72,12 @@ mult (double v1, double v2)
> return v1 * v2;
> }
>
> +long double
> +mult_long_double (long double v1, long double v2)
> +{
> + return v1 * v2;
> +}
> +
> double
> mult_noproto (v1, v2)
> double v1, v2;
> @@ -79,6 +85,13 @@ mult_noproto (v1, v2)
> return v1 * v2;
> }
>
> +long double
> +mult_long_double_noproto (v1, v2)
> + long double v1, v2;
> +{
> + return v1 * v2;
> +}
Not that it really matters, but the ordering seems a bit weird, the
existing functions are all:
X
X_noproto
Y
Y_noproto
etc...
but you broke this pattern. I only mention it because I have some
actual worthwhile points to raise below...
> +
> uint8_t
> add8 (uint8_t v1, uint8_t v2)
> {
> diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
> index e4138a801da..1a16e86ed2c 100644
> --- a/gdb/testsuite/gdb.base/nodebug.exp
> +++ b/gdb/testsuite/gdb.base/nodebug.exp
> @@ -78,6 +78,12 @@ proc test_call_promotion {} {
> gdb_test "p ((double (*) ()) mult_noproto)(2.0f, 3.0f)" " = 6"
> gdb_test "p ((double (*) ()) mult_noproto)(2.0, 3.0)" " = 6"
>
> + # Same, but for long double.
> + gdb_test "p (long double) mult_long_double(2.0L, 3.0L)" " = 6"
> + gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)" " = 6"
> + gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2, 3)" " = 6"
> + gdb_test "p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)" " = 6"
I noticed that the double test also includes a case which tests float to
double promotion, but that case is skipped here. Wouldn't it be a good
idea to include both float to long double and double to long double
tests here too?
Thanks,
Andrew
> +
> # Check that GDB promotes char->int correctly.
> gdb_test "p /d (uint8) add8((uint8) 2, (uint8) 3)" " = 5"
> gdb_test "p /d ((uint8 (*) (uint8, uint8)) add8)((uint8) 2, (uint8) 3)" " = 5"
> --
> 2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 1/4] gdb.base/nodebug.exp: Add long double testing
2026-07-16 21:14 ` Andrew Burgess
@ 2026-07-17 13:59 ` Pedro Alves
2026-07-22 18:41 ` Andrew Burgess
0 siblings, 1 reply; 15+ messages in thread
From: Pedro Alves @ 2026-07-17 13:59 UTC (permalink / raw)
To: Andrew Burgess, gdb-patches
On 2026-07-16 22:14, Andrew Burgess wrote:
> Pedro Alves <pedro@palves.net> writes:
...
> Not that it really matters, but the ordering seems a bit weird, the
> existing functions are all:
>
> X
> X_noproto
> Y
> Y_noproto
> etc...
>
> but you broke this pattern.
Whoops, that was not intentional. I think I misread the pattern earlier. I reordered it now:
$ grep "^mult" testsuite/gdb.base/nodebug.c
multf (float v1, float v2)
multf_noproto (v1, v2)
mult (double v1, double v2)
mult_noproto (v1, v2)
mult_long_double (long double v1, long double v2)
mult_long_double_noproto (v1, v2)
Thanks for spotting this.
> I only mention it because I have some
> actual worthwhile points to raise below...
>
>> +
>> uint8_t
>> add8 (uint8_t v1, uint8_t v2)
>> {
>> diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
>> index e4138a801da..1a16e86ed2c 100644
>> --- a/gdb/testsuite/gdb.base/nodebug.exp
>> +++ b/gdb/testsuite/gdb.base/nodebug.exp
>> @@ -78,6 +78,12 @@ proc test_call_promotion {} {
>> gdb_test "p ((double (*) ()) mult_noproto)(2.0f, 3.0f)" " = 6"
>> gdb_test "p ((double (*) ()) mult_noproto)(2.0, 3.0)" " = 6"
>>
>> + # Same, but for long double.
>> + gdb_test "p (long double) mult_long_double(2.0L, 3.0L)" " = 6"
>> + gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)" " = 6"
>> + gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2, 3)" " = 6"
>> + gdb_test "p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)" " = 6"
>
> I noticed that the double test also includes a case which tests float to
> double promotion, but that case is skipped here. Wouldn't it be a good
> idea to include both float to long double and double to long double
> tests here too?
That's because the double test is exercising the standard C default argument
promotion rules, for floating point, which says that for non-prototyped functions,
float is promoted to double.
So for this float function:
float
multf_noproto (v1, v2)
float v1, v2;
{
return v1 * v2;
}
called like so:
multif_noproto (1.0f, 2.0f);
this happens:
1. Caller promotes 1.0f/2.0f to double, passes the double values.
2. Callee receives doubles.
3. Callee's prologue converts to float, because the declared param type is float.
4. Body uses v1/v2 as float.
================================
And for the double case:
double
mult_noproto (v1, v2)
double v1, v2;
{
return v1 * v2;
}
called like so:
multi_noproto (1.0f, 2.0f);
this happens:
1. Caller promotes 1.0f/2.0f to double, passes the double values.
2. Callee receives a double.
3. Body uses v1/v2 as double.
================================
The long double case is different. The C default promotion is float->double, NOT float->long double.
long double
mult_long_double_noproto (v1, v2)
long double v1, v2;
{
return v1 * v2;
}
mult_long_double_noproto (1.0f, 2.0f);
so this happens:
1. Caller promotes 1.0f/2.0f to double, passes the double values.
2. Callee receives doubles.
3. Body uses v1/v2 as long double. (with no conversion! undefined behavior.)
On ABIs where double and long double are distinct types/sizes, the body sees bogus/corrupt values.
===============================
For the prototyped case, the calls where we pass int, like:
p ((float (*) (float, float)) multf)(2, 3)
cover coercion from int to declared type, which is basically testing that gdb does a cast there.
testing float -> double, etc. for the prototyped cases would not add extra coverage, as it'd just
be testing that gdb knows how to cast from float -> double.
I've added some comments to the test to try to make it a little clearer. I also corrected a couple
references to "coercion" to "promotion" to be more accurate. The existing comments are using the terms
interchangeably, but that's not 100% correct.
Let me know what you think.
From 3f7db94982bb02473e89199a93dde2d27e06014a Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Tue, 14 Jul 2026 00:34:43 +0100
Subject: [PATCH] gdb.base/nodebug.exp: Add long double testing
gdb.base/nodebug.exp is missing testing calling long double functions.
This commit adds such tests.
With a GDB that doesn't know that "long double" is 64-bit on
x86_64-pc-windows-msvc, we get:
FAIL: gdb.base/nodebug.exp: p (long double) mult_long_double(2.0L, 3.0L)
FAIL: gdb.base/nodebug.exp: p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)
FAIL: gdb.base/nodebug.exp: p ((long double (*) (long double, long double)) mult_long_double)(2, 3)
FAIL: gdb.base/nodebug.exp: p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)
Passes cleanly on:
- x86_64-pc-linux-gnu
- x86_64-w64-mingw32
- x86_64-pc-windows-msvc, with the "long double" fix
Change-Id: If9ee749187e1d30fedcba17ae12634f3bd90de2f
---
gdb/testsuite/gdb.base/nodebug.c | 13 +++++++++++++
gdb/testsuite/gdb.base/nodebug.exp | 21 ++++++++++++++++-----
2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/gdb/testsuite/gdb.base/nodebug.c b/gdb/testsuite/gdb.base/nodebug.c
index c7bc93991b8..00e854844bf 100644
--- a/gdb/testsuite/gdb.base/nodebug.c
+++ b/gdb/testsuite/gdb.base/nodebug.c
@@ -79,6 +79,19 @@ mult_noproto (v1, v2)
return v1 * v2;
}
+long double
+mult_long_double (long double v1, long double v2)
+{
+ return v1 * v2;
+}
+
+long double
+mult_long_double_noproto (v1, v2)
+ long double v1, v2;
+{
+ return v1 * v2;
+}
+
uint8_t
add8 (uint8_t v1, uint8_t v2)
{
diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
index e4138a801da..7a5ab273bde 100644
--- a/gdb/testsuite/gdb.base/nodebug.exp
+++ b/gdb/testsuite/gdb.base/nodebug.exp
@@ -51,8 +51,8 @@ proc nodebug_runto {func} {
}
# Test calling no-debug functions involving argument types that may
-# require coercion/promotion, both prototyped and unprototyped, both
-# return-type-cast style, and function-pointer-cast styles.
+# require coercion or promotion, both prototyped and unprototyped,
+# both return-type-cast style, and function-pointer-cast styles.
proc test_call_promotion {} {
if {[target_info exists gdb,cannot_call_functions]} {
return
@@ -60,14 +60,15 @@ proc test_call_promotion {} {
# Call prototyped function with float parameters via both
# return-type cast and function-pointer cast. This checks that
- # GDB doesn't do float->double coercion.
+ # GDB doesn't do float->double promotion.
gdb_test "p (float) multf(2.0f, 3.0f)" " = 6"
- gdb_test "p ((float (*) (float, float)) multf)(2, 3)" " = 6"
gdb_test "p ((float (*) (float, float)) multf)(2.0f, 3.0f)" " = 6"
+ # This tests int->float coercion.
+ gdb_test "p ((float (*) (float, float)) multf)(2, 3)" " = 6"
# Call unprototyped function with float parameters via
# function-pointer cast, only. return-type cast assumes
- # protototyped. Check that GDB does float->double coercion.
+ # prototyped. Check that GDB does float->double promotion.
gdb_test "p ((float (*) ()) multf_noproto)(2.0f, 3.0f)" " = 6"
gdb_test "p ((float (*) ()) multf_noproto)(2.0, 3.0)" " = 6"
@@ -78,6 +79,16 @@ proc test_call_promotion {} {
gdb_test "p ((double (*) ()) mult_noproto)(2.0f, 3.0f)" " = 6"
gdb_test "p ((double (*) ()) mult_noproto)(2.0, 3.0)" " = 6"
+ # Same, but for long double.
+ gdb_test "p (long double) mult_long_double(2.0L, 3.0L)" " = 6"
+ gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)" " = 6"
+ gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2, 3)" " = 6"
+ # For unprototyped calls, the standard C default argument
+ # promotion (for floating point) applies only to float and
+ # promotes to double, so test only with the expected type, using
+ # L-suffixed literals to pass long doubles.
+ gdb_test "p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)" " = 6"
+
# Check that GDB promotes char->int correctly.
gdb_test "p /d (uint8) add8((uint8) 2, (uint8) 3)" " = 5"
gdb_test "p /d ((uint8 (*) (uint8, uint8)) add8)((uint8) 2, (uint8) 3)" " = 5"
base-commit: 490469846dcef89fe53668bdbba73591c64bed61
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 1/4] gdb.base/nodebug.exp: Add long double testing
2026-07-17 13:59 ` Pedro Alves
@ 2026-07-22 18:41 ` Andrew Burgess
0 siblings, 0 replies; 15+ messages in thread
From: Andrew Burgess @ 2026-07-22 18:41 UTC (permalink / raw)
To: Pedro Alves, gdb-patches
Pedro Alves <pedro@palves.net> writes:
> On 2026-07-16 22:14, Andrew Burgess wrote:
>> Pedro Alves <pedro@palves.net> writes:
> ...
>
>> Not that it really matters, but the ordering seems a bit weird, the
>> existing functions are all:
>>
>> X
>> X_noproto
>> Y
>> Y_noproto
>> etc...
>>
>> but you broke this pattern.
>
> Whoops, that was not intentional. I think I misread the pattern earlier. I reordered it now:
>
> $ grep "^mult" testsuite/gdb.base/nodebug.c
> multf (float v1, float v2)
> multf_noproto (v1, v2)
> mult (double v1, double v2)
> mult_noproto (v1, v2)
> mult_long_double (long double v1, long double v2)
> mult_long_double_noproto (v1, v2)
>
> Thanks for spotting this.
>
>> I only mention it because I have some
>> actual worthwhile points to raise below...
>>
>>> +
>>> uint8_t
>>> add8 (uint8_t v1, uint8_t v2)
>>> {
>>> diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
>>> index e4138a801da..1a16e86ed2c 100644
>>> --- a/gdb/testsuite/gdb.base/nodebug.exp
>>> +++ b/gdb/testsuite/gdb.base/nodebug.exp
>>> @@ -78,6 +78,12 @@ proc test_call_promotion {} {
>>> gdb_test "p ((double (*) ()) mult_noproto)(2.0f, 3.0f)" " = 6"
>>> gdb_test "p ((double (*) ()) mult_noproto)(2.0, 3.0)" " = 6"
>>>
>>> + # Same, but for long double.
>>> + gdb_test "p (long double) mult_long_double(2.0L, 3.0L)" " = 6"
>>> + gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)" " = 6"
>>> + gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2, 3)" " = 6"
>>> + gdb_test "p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)" " = 6"
>>
>> I noticed that the double test also includes a case which tests float to
>> double promotion, but that case is skipped here. Wouldn't it be a good
>> idea to include both float to long double and double to long double
>> tests here too?
>
> That's because the double test is exercising the standard C default argument
> promotion rules, for floating point, which says that for non-prototyped functions,
> float is promoted to double.
>
> So for this float function:
>
> float
> multf_noproto (v1, v2)
> float v1, v2;
> {
> return v1 * v2;
> }
>
> called like so:
>
> multif_noproto (1.0f, 2.0f);
>
> this happens:
>
> 1. Caller promotes 1.0f/2.0f to double, passes the double values.
> 2. Callee receives doubles.
> 3. Callee's prologue converts to float, because the declared param type is float.
> 4. Body uses v1/v2 as float.
>
> ================================
>
> And for the double case:
>
> double
> mult_noproto (v1, v2)
> double v1, v2;
> {
> return v1 * v2;
> }
>
> called like so:
>
> multi_noproto (1.0f, 2.0f);
>
> this happens:
>
> 1. Caller promotes 1.0f/2.0f to double, passes the double values.
> 2. Callee receives a double.
> 3. Body uses v1/v2 as double.
>
> ================================
>
> The long double case is different. The C default promotion is float->double, NOT float->long double.
>
> long double
> mult_long_double_noproto (v1, v2)
> long double v1, v2;
> {
> return v1 * v2;
> }
>
> mult_long_double_noproto (1.0f, 2.0f);
>
> so this happens:
>
> 1. Caller promotes 1.0f/2.0f to double, passes the double values.
> 2. Callee receives doubles.
> 3. Body uses v1/v2 as long double. (with no conversion! undefined behavior.)
>
> On ABIs where double and long double are distinct types/sizes, the body sees bogus/corrupt values.
>
> ===============================
>
> For the prototyped case, the calls where we pass int, like:
>
> p ((float (*) (float, float)) multf)(2, 3)
>
> cover coercion from int to declared type, which is basically testing that gdb does a cast there.
> testing float -> double, etc. for the prototyped cases would not add extra coverage, as it'd just
> be testing that gdb knows how to cast from float -> double.
>
>
>
> I've added some comments to the test to try to make it a little clearer. I also corrected a couple
> references to "coercion" to "promotion" to be more accurate. The existing comments are using the terms
> interchangeably, but that's not 100% correct.
>
> Let me know what you think.
Sorry, missed this. Thanks for the explanation above. LGTM.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Thanks,
Andrew
>
> From 3f7db94982bb02473e89199a93dde2d27e06014a Mon Sep 17 00:00:00 2001
> From: Pedro Alves <pedro@palves.net>
> Date: Tue, 14 Jul 2026 00:34:43 +0100
> Subject: [PATCH] gdb.base/nodebug.exp: Add long double testing
>
> gdb.base/nodebug.exp is missing testing calling long double functions.
> This commit adds such tests.
>
> With a GDB that doesn't know that "long double" is 64-bit on
> x86_64-pc-windows-msvc, we get:
>
> FAIL: gdb.base/nodebug.exp: p (long double) mult_long_double(2.0L, 3.0L)
> FAIL: gdb.base/nodebug.exp: p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)
> FAIL: gdb.base/nodebug.exp: p ((long double (*) (long double, long double)) mult_long_double)(2, 3)
> FAIL: gdb.base/nodebug.exp: p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)
>
> Passes cleanly on:
>
> - x86_64-pc-linux-gnu
> - x86_64-w64-mingw32
> - x86_64-pc-windows-msvc, with the "long double" fix
>
> Change-Id: If9ee749187e1d30fedcba17ae12634f3bd90de2f
> ---
> gdb/testsuite/gdb.base/nodebug.c | 13 +++++++++++++
> gdb/testsuite/gdb.base/nodebug.exp | 21 ++++++++++++++++-----
> 2 files changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.base/nodebug.c b/gdb/testsuite/gdb.base/nodebug.c
> index c7bc93991b8..00e854844bf 100644
> --- a/gdb/testsuite/gdb.base/nodebug.c
> +++ b/gdb/testsuite/gdb.base/nodebug.c
> @@ -79,6 +79,19 @@ mult_noproto (v1, v2)
> return v1 * v2;
> }
>
> +long double
> +mult_long_double (long double v1, long double v2)
> +{
> + return v1 * v2;
> +}
> +
> +long double
> +mult_long_double_noproto (v1, v2)
> + long double v1, v2;
> +{
> + return v1 * v2;
> +}
> +
> uint8_t
> add8 (uint8_t v1, uint8_t v2)
> {
> diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
> index e4138a801da..7a5ab273bde 100644
> --- a/gdb/testsuite/gdb.base/nodebug.exp
> +++ b/gdb/testsuite/gdb.base/nodebug.exp
> @@ -51,8 +51,8 @@ proc nodebug_runto {func} {
> }
>
> # Test calling no-debug functions involving argument types that may
> -# require coercion/promotion, both prototyped and unprototyped, both
> -# return-type-cast style, and function-pointer-cast styles.
> +# require coercion or promotion, both prototyped and unprototyped,
> +# both return-type-cast style, and function-pointer-cast styles.
> proc test_call_promotion {} {
> if {[target_info exists gdb,cannot_call_functions]} {
> return
> @@ -60,14 +60,15 @@ proc test_call_promotion {} {
>
> # Call prototyped function with float parameters via both
> # return-type cast and function-pointer cast. This checks that
> - # GDB doesn't do float->double coercion.
> + # GDB doesn't do float->double promotion.
> gdb_test "p (float) multf(2.0f, 3.0f)" " = 6"
> - gdb_test "p ((float (*) (float, float)) multf)(2, 3)" " = 6"
> gdb_test "p ((float (*) (float, float)) multf)(2.0f, 3.0f)" " = 6"
> + # This tests int->float coercion.
> + gdb_test "p ((float (*) (float, float)) multf)(2, 3)" " = 6"
>
> # Call unprototyped function with float parameters via
> # function-pointer cast, only. return-type cast assumes
> - # protototyped. Check that GDB does float->double coercion.
> + # prototyped. Check that GDB does float->double promotion.
> gdb_test "p ((float (*) ()) multf_noproto)(2.0f, 3.0f)" " = 6"
> gdb_test "p ((float (*) ()) multf_noproto)(2.0, 3.0)" " = 6"
>
> @@ -78,6 +79,16 @@ proc test_call_promotion {} {
> gdb_test "p ((double (*) ()) mult_noproto)(2.0f, 3.0f)" " = 6"
> gdb_test "p ((double (*) ()) mult_noproto)(2.0, 3.0)" " = 6"
>
> + # Same, but for long double.
> + gdb_test "p (long double) mult_long_double(2.0L, 3.0L)" " = 6"
> + gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2.0L, 3.0L)" " = 6"
> + gdb_test "p ((long double (*) (long double, long double)) mult_long_double)(2, 3)" " = 6"
> + # For unprototyped calls, the standard C default argument
> + # promotion (for floating point) applies only to float and
> + # promotes to double, so test only with the expected type, using
> + # L-suffixed literals to pass long doubles.
> + gdb_test "p ((long double (*) ()) mult_long_double_noproto)(2.0L, 3.0L)" " = 6"
> +
> # Check that GDB promotes char->int correctly.
> gdb_test "p /d (uint8) add8((uint8) 2, (uint8) 3)" " = 5"
> gdb_test "p /d ((uint8 (*) (uint8, uint8)) add8)((uint8) 2, (uint8) 3)" " = 5"
>
> base-commit: 490469846dcef89fe53668bdbba73591c64bed61
> --
> 2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 2/4] gdb.base/callfuncs.exp: Adjust for Windows
2026-07-14 22:06 [PATCH 0/4] gdb/testsuite: "long double" infcall tests Pedro Alves
2026-07-14 22:06 ` [PATCH 1/4] gdb.base/nodebug.exp: Add long double testing Pedro Alves
@ 2026-07-14 22:06 ` Pedro Alves
2026-07-14 22:25 ` Pedro Alves
2026-07-14 22:06 ` [PATCH 3/4] gdb.base/callfuncs.c: factor out float/double functions Pedro Alves
` (2 subsequent siblings)
4 siblings, 1 reply; 15+ messages in thread
From: Pedro Alves @ 2026-07-14 22:06 UTC (permalink / raw)
To: gdb-patches
On Windows, gdb.base/callfuncs.exp currently ends up skipping the
"noproto" tests, like:
UNTESTED: gdb.base/callfuncs.exp: noproto: failed to prepare
This is because the testcase tries to overwrite the executable while
GDB has the executable still open, which doesn't work on Windows:
Executing on host: x86_64-w64-mingw32-gcc ... -o .../gdb.base/callfuncs/callfuncs
.../x86_64-w64-mingw32/bin/ld.exe: cannot open output file .../gdb.base/callfuncs/callfuncs.exe: Permission denied
Fix this with two changes:
- Compile the prototyped and non-prototyped executables to two
separate executables. This is just what we normally do, so that
it's convenient to test manually against either of the executables.
- Restart GDB instead of just re-running to main.
Strictly speaking, either of the changes alone would fix it, but I
think both are useful to do.
Change-Id: I496e0da65f9d484079c5d9a1222104bec39ee98b
---
gdb/testsuite/gdb.base/callfuncs.exp | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp
index f2870c577f2..f020100ce8b 100644
--- a/gdb/testsuite/gdb.base/callfuncs.exp
+++ b/gdb/testsuite/gdb.base/callfuncs.exp
@@ -334,12 +334,18 @@ proc fetch_all_registers {test} {
# Global used by RERUN_AND_PREPARE to make test names unique.
set rerun_count 0
-proc rerun_and_prepare {} {
+proc rerun_and_prepare {prototypes} {
global rerun_count
+ clean_restart $::testfile-$prototypes
+
incr rerun_count
with_test_prefix "rerun number ${rerun_count}" {
+ gdb_test_no_output "set print sevenbit-strings"
+ gdb_test_no_output "set print address off"
+ gdb_test_no_output "set width 0"
+
if { ![runto_main] } {
return
}
@@ -359,11 +365,7 @@ proc rerun_and_prepare {} {
}
proc perform_all_tests {prototypes} {
- gdb_test_no_output "set print sevenbit-strings"
- gdb_test_no_output "set print address off"
- gdb_test_no_output "set width 0"
-
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Save all register contents.
set old_reg_content \
@@ -382,7 +384,7 @@ proc perform_all_tests {prototypes} {
fail "gdb function calls preserve register contents"
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Save all register contents.
set old_reg_content \
[fetch_all_registers "retrieve original register contents 2"]
@@ -408,7 +410,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
# Save all register contents.
@@ -434,7 +436,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
# Save all register contents.
@@ -459,7 +461,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
set old_reg_content \
@@ -547,12 +549,12 @@ proc perform_all_tests {prototypes} {
# Perform all tests with and without function prototypes.
-if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
+if { ![prepare_for_testing "failed to prepare" $testfile-1 $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
perform_all_tests 1
}
with_test_prefix "noproto" {
- if { ![prepare_for_testing "failed to prepare" $testfile $srcfile \
+ if { ![prepare_for_testing "failed to prepare" $testfile-0 $srcfile \
"$compile_flags additional_flags=-DNO_PROTOTYPES"] } {
perform_all_tests 0
}
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 2/4] gdb.base/callfuncs.exp: Adjust for Windows
2026-07-14 22:06 ` [PATCH 2/4] gdb.base/callfuncs.exp: Adjust for Windows Pedro Alves
@ 2026-07-14 22:25 ` Pedro Alves
2026-07-16 21:26 ` Andrew Burgess
0 siblings, 1 reply; 15+ messages in thread
From: Pedro Alves @ 2026-07-14 22:25 UTC (permalink / raw)
To: gdb-patches
A bit of self-review...
I did the same mistake I did recently, again. Here:
> -if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
> +if { ![prepare_for_testing "failed to prepare" $testfile-1 $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
> perform_all_tests 1
> }
>
> with_test_prefix "noproto" {
> - if { ![prepare_for_testing "failed to prepare" $testfile $srcfile \
> + if { ![prepare_for_testing "failed to prepare" $testfile-0 $srcfile \
> "$compile_flags additional_flags=-DNO_PROTOTYPES"] } {
> perform_all_tests 0
> }
Since rerun_and_prepare now always restart GDB, these prepare_for_testing calls
can be turned into build_executable calls.
I've done that now. The testcase still passes cleanly.
From 974b26155dd4a128a0382b3b0b08d60d78f0a0de Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Tue, 14 Jul 2026 19:48:30 +0100
Subject: [PATCH] gdb.base/callfuncs.exp: Adjust for Windows
On Windows, gdb.base/callfuncs.exp currently ends up skipping the
"noproto" tests, like:
UNTESTED: gdb.base/callfuncs.exp: noproto: failed to prepare
This is because the testcase tries to overwrite the executable while
GDB has the executable still open, which doesn't work on Windows:
Executing on host: x86_64-w64-mingw32-gcc ... -o .../gdb.base/callfuncs/callfuncs
.../x86_64-w64-mingw32/bin/ld.exe: cannot open output file .../gdb.base/callfuncs/callfuncs.exe: Permission denied
Fix this with two changes:
- Compile the prototyped and non-prototyped executables to two
separate executables. This is just what we normally do, so that
it's convenient to test manually against either of the executables.
- Restart GDB instead of just re-running to main.
Strictly speaking, either of the changes alone would fix it, but I
think both are useful to do.
Change-Id: I496e0da65f9d484079c5d9a1222104bec39ee98b
---
gdb/testsuite/gdb.base/callfuncs.exp | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp
index f2870c577f2..0ac1c603351 100644
--- a/gdb/testsuite/gdb.base/callfuncs.exp
+++ b/gdb/testsuite/gdb.base/callfuncs.exp
@@ -334,12 +334,18 @@ proc fetch_all_registers {test} {
# Global used by RERUN_AND_PREPARE to make test names unique.
set rerun_count 0
-proc rerun_and_prepare {} {
+proc rerun_and_prepare {prototypes} {
global rerun_count
+ clean_restart $::testfile-$prototypes
+
incr rerun_count
with_test_prefix "rerun number ${rerun_count}" {
+ gdb_test_no_output "set print sevenbit-strings"
+ gdb_test_no_output "set print address off"
+ gdb_test_no_output "set width 0"
+
if { ![runto_main] } {
return
}
@@ -359,11 +365,7 @@ proc rerun_and_prepare {} {
}
proc perform_all_tests {prototypes} {
- gdb_test_no_output "set print sevenbit-strings"
- gdb_test_no_output "set print address off"
- gdb_test_no_output "set width 0"
-
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Save all register contents.
set old_reg_content \
@@ -382,7 +384,7 @@ proc perform_all_tests {prototypes} {
fail "gdb function calls preserve register contents"
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Save all register contents.
set old_reg_content \
[fetch_all_registers "retrieve original register contents 2"]
@@ -408,7 +410,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
# Save all register contents.
@@ -434,7 +436,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
# Save all register contents.
@@ -459,7 +461,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
set old_reg_content \
@@ -547,12 +549,12 @@ proc perform_all_tests {prototypes} {
# Perform all tests with and without function prototypes.
-if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
+if { ![build_executable "failed to build" $testfile-1 $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
perform_all_tests 1
}
with_test_prefix "noproto" {
- if { ![prepare_for_testing "failed to prepare" $testfile $srcfile \
+ if { ![build_executable "failed to build" $testfile-0 $srcfile \
"$compile_flags additional_flags=-DNO_PROTOTYPES"] } {
perform_all_tests 0
}
base-commit: 490469846dcef89fe53668bdbba73591c64bed61
prerequisite-patch-id: f9480ec6b27aac188161579fdec6f08d5065ac6f
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 2/4] gdb.base/callfuncs.exp: Adjust for Windows
2026-07-14 22:25 ` Pedro Alves
@ 2026-07-16 21:26 ` Andrew Burgess
2026-07-17 14:27 ` Pedro Alves
0 siblings, 1 reply; 15+ messages in thread
From: Andrew Burgess @ 2026-07-16 21:26 UTC (permalink / raw)
To: Pedro Alves, gdb-patches
Pedro Alves <pedro@palves.net> writes:
> A bit of self-review...
>
> I did the same mistake I did recently, again. Here:
>
>> -if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
>> +if { ![prepare_for_testing "failed to prepare" $testfile-1 $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
>> perform_all_tests 1
>> }
>>
>> with_test_prefix "noproto" {
>> - if { ![prepare_for_testing "failed to prepare" $testfile $srcfile \
>> + if { ![prepare_for_testing "failed to prepare" $testfile-0 $srcfile \
>> "$compile_flags additional_flags=-DNO_PROTOTYPES"] } {
>> perform_all_tests 0
>> }
>
> Since rerun_and_prepare now always restart GDB, these prepare_for_testing calls
> can be turned into build_executable calls.
>
> I've done that now. The testcase still passes cleanly.
>
> From 974b26155dd4a128a0382b3b0b08d60d78f0a0de Mon Sep 17 00:00:00 2001
> From: Pedro Alves <pedro@palves.net>
> Date: Tue, 14 Jul 2026 19:48:30 +0100
> Subject: [PATCH] gdb.base/callfuncs.exp: Adjust for Windows
>
> On Windows, gdb.base/callfuncs.exp currently ends up skipping the
> "noproto" tests, like:
>
> UNTESTED: gdb.base/callfuncs.exp: noproto: failed to prepare
>
> This is because the testcase tries to overwrite the executable while
> GDB has the executable still open, which doesn't work on Windows:
>
> Executing on host: x86_64-w64-mingw32-gcc ... -o .../gdb.base/callfuncs/callfuncs
> .../x86_64-w64-mingw32/bin/ld.exe: cannot open output file .../gdb.base/callfuncs/callfuncs.exe: Permission denied
>
> Fix this with two changes:
>
> - Compile the prototyped and non-prototyped executables to two
> separate executables. This is just what we normally do, so that
> it's convenient to test manually against either of the executables.
>
> - Restart GDB instead of just re-running to main.
>
> Strictly speaking, either of the changes alone would fix it, but I
> think both are useful to do.
Is this true? After the first perform_all_tests call GDB is still
running and has the executable file open. Without the separate
filenames the second build_executable call will try to change the
executable that GDB holds open.
All you've done is split prepare_for_testing into build_executable and
clean_restart, but the order hasn't changed (and you call clean_restart
more often now).
Not that I object to these changes, I just disagree with the last
sentence as I don't think the clean_restart change alone will fix the
problem.
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
Thanks,
Andrew
>
> Change-Id: I496e0da65f9d484079c5d9a1222104bec39ee98b
> ---
> gdb/testsuite/gdb.base/callfuncs.exp | 26 ++++++++++++++------------
> 1 file changed, 14 insertions(+), 12 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp
> index f2870c577f2..0ac1c603351 100644
> --- a/gdb/testsuite/gdb.base/callfuncs.exp
> +++ b/gdb/testsuite/gdb.base/callfuncs.exp
> @@ -334,12 +334,18 @@ proc fetch_all_registers {test} {
> # Global used by RERUN_AND_PREPARE to make test names unique.
> set rerun_count 0
>
> -proc rerun_and_prepare {} {
> +proc rerun_and_prepare {prototypes} {
> global rerun_count
>
> + clean_restart $::testfile-$prototypes
> +
> incr rerun_count
> with_test_prefix "rerun number ${rerun_count}" {
>
> + gdb_test_no_output "set print sevenbit-strings"
> + gdb_test_no_output "set print address off"
> + gdb_test_no_output "set width 0"
> +
> if { ![runto_main] } {
> return
> }
> @@ -359,11 +365,7 @@ proc rerun_and_prepare {} {
> }
>
> proc perform_all_tests {prototypes} {
> - gdb_test_no_output "set print sevenbit-strings"
> - gdb_test_no_output "set print address off"
> - gdb_test_no_output "set width 0"
> -
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
>
> # Save all register contents.
> set old_reg_content \
> @@ -382,7 +384,7 @@ proc perform_all_tests {prototypes} {
> fail "gdb function calls preserve register contents"
> }
>
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
> # Save all register contents.
> set old_reg_content \
> [fetch_all_registers "retrieve original register contents 2"]
> @@ -408,7 +410,7 @@ proc perform_all_tests {prototypes} {
> }
> }
>
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
> # Set breakpoint at a function we will call from gdb.
> gdb_breakpoint add
> # Save all register contents.
> @@ -434,7 +436,7 @@ proc perform_all_tests {prototypes} {
> }
> }
>
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
> # Set breakpoint at a function we will call from gdb.
> gdb_breakpoint add
> # Save all register contents.
> @@ -459,7 +461,7 @@ proc perform_all_tests {prototypes} {
> }
> }
>
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
> # Set breakpoint at a function we will call from gdb.
> gdb_breakpoint add
> set old_reg_content \
> @@ -547,12 +549,12 @@ proc perform_all_tests {prototypes} {
>
> # Perform all tests with and without function prototypes.
>
> -if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
> +if { ![build_executable "failed to build" $testfile-1 $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
> perform_all_tests 1
> }
>
> with_test_prefix "noproto" {
> - if { ![prepare_for_testing "failed to prepare" $testfile $srcfile \
> + if { ![build_executable "failed to build" $testfile-0 $srcfile \
> "$compile_flags additional_flags=-DNO_PROTOTYPES"] } {
> perform_all_tests 0
> }
>
> base-commit: 490469846dcef89fe53668bdbba73591c64bed61
> prerequisite-patch-id: f9480ec6b27aac188161579fdec6f08d5065ac6f
> --
> 2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 2/4] gdb.base/callfuncs.exp: Adjust for Windows
2026-07-16 21:26 ` Andrew Burgess
@ 2026-07-17 14:27 ` Pedro Alves
2026-07-22 18:42 ` Andrew Burgess
0 siblings, 1 reply; 15+ messages in thread
From: Pedro Alves @ 2026-07-17 14:27 UTC (permalink / raw)
To: Andrew Burgess, gdb-patches
On 2026-07-16 22:26, Andrew Burgess wrote:
> Pedro Alves <pedro@palves.net> writes:
>> Strictly speaking, either of the changes alone would fix it, but I
>> think both are useful to do.
>
> Is this true? After the first perform_all_tests call GDB is still
> running and has the executable file open. Without the separate
> filenames the second build_executable call will try to change the
> executable that GDB holds open.
Right, that was sloppy last minute editing, didn't think it that well.
Sorry about that. I was originally going to add add a gdb_exit before the
second compilation, but that would end up more complicated, and I realized
I might as well make the programs have different names, and clean_restart is
handy to reload the new executable, and so I didn't need the gdb_exit
any longer...
> Not that I object to these changes, I just disagree with the last
> sentence as I don't think the clean_restart change alone will fix the
> problem.
>
> Reviewed-By: Andrew Burgess <aburgess@redhat.com>
>
I've removed that last sentence, and added "to pick up the new executable." to
the preceding one.
From a08b0bf87322cc11aace49407382e0f9c4e92078 Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Tue, 14 Jul 2026 19:48:30 +0100
Subject: [PATCH] gdb.base/callfuncs.exp: Adjust for Windows
On Windows, gdb.base/callfuncs.exp currently ends up skipping the
"noproto" tests, like:
UNTESTED: gdb.base/callfuncs.exp: noproto: failed to prepare
This is because the testcase tries to overwrite the executable while
GDB has the executable still open, which doesn't work on Windows:
Executing on host: x86_64-w64-mingw32-gcc ... -o .../gdb.base/callfuncs/callfuncs
.../x86_64-w64-mingw32/bin/ld.exe: cannot open output file .../gdb.base/callfuncs/callfuncs.exe: Permission denied
Fix this with two changes:
- Compile the prototyped and non-prototyped executables to two
separate executables. This is just what we normally do, so that
it's convenient to test manually against either of the executables.
- Restart GDB instead of just re-running to main, to pick up the new
executable.
Change-Id: I496e0da65f9d484079c5d9a1222104bec39ee98b
---
gdb/testsuite/gdb.base/callfuncs.exp | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp
index f2870c577f2..0ac1c603351 100644
--- a/gdb/testsuite/gdb.base/callfuncs.exp
+++ b/gdb/testsuite/gdb.base/callfuncs.exp
@@ -334,12 +334,18 @@ proc fetch_all_registers {test} {
# Global used by RERUN_AND_PREPARE to make test names unique.
set rerun_count 0
-proc rerun_and_prepare {} {
+proc rerun_and_prepare {prototypes} {
global rerun_count
+ clean_restart $::testfile-$prototypes
+
incr rerun_count
with_test_prefix "rerun number ${rerun_count}" {
+ gdb_test_no_output "set print sevenbit-strings"
+ gdb_test_no_output "set print address off"
+ gdb_test_no_output "set width 0"
+
if { ![runto_main] } {
return
}
@@ -359,11 +365,7 @@ proc rerun_and_prepare {} {
}
proc perform_all_tests {prototypes} {
- gdb_test_no_output "set print sevenbit-strings"
- gdb_test_no_output "set print address off"
- gdb_test_no_output "set width 0"
-
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Save all register contents.
set old_reg_content \
@@ -382,7 +384,7 @@ proc perform_all_tests {prototypes} {
fail "gdb function calls preserve register contents"
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Save all register contents.
set old_reg_content \
[fetch_all_registers "retrieve original register contents 2"]
@@ -408,7 +410,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
# Save all register contents.
@@ -434,7 +436,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
# Save all register contents.
@@ -459,7 +461,7 @@ proc perform_all_tests {prototypes} {
}
}
- rerun_and_prepare
+ rerun_and_prepare $prototypes
# Set breakpoint at a function we will call from gdb.
gdb_breakpoint add
set old_reg_content \
@@ -547,12 +549,12 @@ proc perform_all_tests {prototypes} {
# Perform all tests with and without function prototypes.
-if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
+if { ![build_executable "failed to build" $testfile-1 $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
perform_all_tests 1
}
with_test_prefix "noproto" {
- if { ![prepare_for_testing "failed to prepare" $testfile $srcfile \
+ if { ![build_executable "failed to build" $testfile-0 $srcfile \
"$compile_flags additional_flags=-DNO_PROTOTYPES"] } {
perform_all_tests 0
}
base-commit: 490469846dcef89fe53668bdbba73591c64bed61
prerequisite-patch-id: 4252e00ad379be8852a564f351cbd3e3b8a5f0ec
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 2/4] gdb.base/callfuncs.exp: Adjust for Windows
2026-07-17 14:27 ` Pedro Alves
@ 2026-07-22 18:42 ` Andrew Burgess
0 siblings, 0 replies; 15+ messages in thread
From: Andrew Burgess @ 2026-07-22 18:42 UTC (permalink / raw)
To: Pedro Alves, gdb-patches
Pedro Alves <pedro@palves.net> writes:
> On 2026-07-16 22:26, Andrew Burgess wrote:
>> Pedro Alves <pedro@palves.net> writes:
>>> Strictly speaking, either of the changes alone would fix it, but I
>>> think both are useful to do.
>>
>> Is this true? After the first perform_all_tests call GDB is still
>> running and has the executable file open. Without the separate
>> filenames the second build_executable call will try to change the
>> executable that GDB holds open.
>
> Right, that was sloppy last minute editing, didn't think it that well.
> Sorry about that. I was originally going to add add a gdb_exit before the
> second compilation, but that would end up more complicated, and I realized
> I might as well make the programs have different names, and clean_restart is
> handy to reload the new executable, and so I didn't need the gdb_exit
> any longer...
>
>
>> Not that I object to these changes, I just disagree with the last
>> sentence as I don't think the clean_restart change alone will fix the
>> problem.
>>
>> Reviewed-By: Andrew Burgess <aburgess@redhat.com>
>>
>
> I've removed that last sentence, and added "to pick up the new executable." to
> the preceding one.
>
> From a08b0bf87322cc11aace49407382e0f9c4e92078 Mon Sep 17 00:00:00 2001
> From: Pedro Alves <pedro@palves.net>
> Date: Tue, 14 Jul 2026 19:48:30 +0100
> Subject: [PATCH] gdb.base/callfuncs.exp: Adjust for Windows
>
> On Windows, gdb.base/callfuncs.exp currently ends up skipping the
> "noproto" tests, like:
>
> UNTESTED: gdb.base/callfuncs.exp: noproto: failed to prepare
>
> This is because the testcase tries to overwrite the executable while
> GDB has the executable still open, which doesn't work on Windows:
>
> Executing on host: x86_64-w64-mingw32-gcc ... -o .../gdb.base/callfuncs/callfuncs
> .../x86_64-w64-mingw32/bin/ld.exe: cannot open output file .../gdb.base/callfuncs/callfuncs.exe: Permission denied
>
> Fix this with two changes:
>
> - Compile the prototyped and non-prototyped executables to two
> separate executables. This is just what we normally do, so that
> it's convenient to test manually against either of the executables.
>
> - Restart GDB instead of just re-running to main, to pick up the new
> executable.
LGTM.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Thanks,
Andrew
>
> Change-Id: I496e0da65f9d484079c5d9a1222104bec39ee98b
> ---
> gdb/testsuite/gdb.base/callfuncs.exp | 26 ++++++++++++++------------
> 1 file changed, 14 insertions(+), 12 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp
> index f2870c577f2..0ac1c603351 100644
> --- a/gdb/testsuite/gdb.base/callfuncs.exp
> +++ b/gdb/testsuite/gdb.base/callfuncs.exp
> @@ -334,12 +334,18 @@ proc fetch_all_registers {test} {
> # Global used by RERUN_AND_PREPARE to make test names unique.
> set rerun_count 0
>
> -proc rerun_and_prepare {} {
> +proc rerun_and_prepare {prototypes} {
> global rerun_count
>
> + clean_restart $::testfile-$prototypes
> +
> incr rerun_count
> with_test_prefix "rerun number ${rerun_count}" {
>
> + gdb_test_no_output "set print sevenbit-strings"
> + gdb_test_no_output "set print address off"
> + gdb_test_no_output "set width 0"
> +
> if { ![runto_main] } {
> return
> }
> @@ -359,11 +365,7 @@ proc rerun_and_prepare {} {
> }
>
> proc perform_all_tests {prototypes} {
> - gdb_test_no_output "set print sevenbit-strings"
> - gdb_test_no_output "set print address off"
> - gdb_test_no_output "set width 0"
> -
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
>
> # Save all register contents.
> set old_reg_content \
> @@ -382,7 +384,7 @@ proc perform_all_tests {prototypes} {
> fail "gdb function calls preserve register contents"
> }
>
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
> # Save all register contents.
> set old_reg_content \
> [fetch_all_registers "retrieve original register contents 2"]
> @@ -408,7 +410,7 @@ proc perform_all_tests {prototypes} {
> }
> }
>
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
> # Set breakpoint at a function we will call from gdb.
> gdb_breakpoint add
> # Save all register contents.
> @@ -434,7 +436,7 @@ proc perform_all_tests {prototypes} {
> }
> }
>
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
> # Set breakpoint at a function we will call from gdb.
> gdb_breakpoint add
> # Save all register contents.
> @@ -459,7 +461,7 @@ proc perform_all_tests {prototypes} {
> }
> }
>
> - rerun_and_prepare
> + rerun_and_prepare $prototypes
> # Set breakpoint at a function we will call from gdb.
> gdb_breakpoint add
> set old_reg_content \
> @@ -547,12 +549,12 @@ proc perform_all_tests {prototypes} {
>
> # Perform all tests with and without function prototypes.
>
> -if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
> +if { ![build_executable "failed to build" $testfile-1 $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } {
> perform_all_tests 1
> }
>
> with_test_prefix "noproto" {
> - if { ![prepare_for_testing "failed to prepare" $testfile $srcfile \
> + if { ![build_executable "failed to build" $testfile-0 $srcfile \
> "$compile_flags additional_flags=-DNO_PROTOTYPES"] } {
> perform_all_tests 0
> }
>
> base-commit: 490469846dcef89fe53668bdbba73591c64bed61
> prerequisite-patch-id: 4252e00ad379be8852a564f351cbd3e3b8a5f0ec
> --
> 2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 3/4] gdb.base/callfuncs.c: factor out float/double functions
2026-07-14 22:06 [PATCH 0/4] gdb/testsuite: "long double" infcall tests Pedro Alves
2026-07-14 22:06 ` [PATCH 1/4] gdb.base/nodebug.exp: Add long double testing Pedro Alves
2026-07-14 22:06 ` [PATCH 2/4] gdb.base/callfuncs.exp: Adjust for Windows Pedro Alves
@ 2026-07-14 22:06 ` Pedro Alves
2026-07-16 21:33 ` Andrew Burgess
2026-07-14 22:06 ` [PATCH 4/4] gdb.base/callfuncs.exp: Exercise "long double" Pedro Alves
2026-07-22 13:01 ` [PATCH 0/4] gdb/testsuite: "long double" infcall tests Pedro Alves
4 siblings, 1 reply; 15+ messages in thread
From: Pedro Alves @ 2026-07-14 22:06 UTC (permalink / raw)
To: gdb-patches
Other than float vs double, t_float_values2 and t_double_values are
identical. Same for t_float_many_args and t_double_many_args.
Adding 'long double' variants would mean even more duplication.
Factor each "values" and "many_args" pair into a macro that generates
the function from the type, so that adding a new type is just one
line.
Tested on x86_64-unknown-linux-gnu.
Change-Id: I43013f4db9ccf1e5d8ac17dc5b557bd44500b9f4
---
gdb/testsuite/gdb.base/callfuncs.c | 138 +++++++++++++----------------
1 file changed, 60 insertions(+), 78 deletions(-)
diff --git a/gdb/testsuite/gdb.base/callfuncs.c b/gdb/testsuite/gdb.base/callfuncs.c
index 1d35272a50e..0e6d9dcdd71 100644
--- a/gdb/testsuite/gdb.base/callfuncs.c
+++ b/gdb/testsuite/gdb.base/callfuncs.c
@@ -345,96 +345,78 @@ float float_arg1, float_arg2;
&& (float_arg2 - float_val2) > -DELTA);
}
-int
+/* The parameter list of a t_TYPE_values function. Split out into
+ prototyped vs non-prototyped variants because a macro body cannot
+ contain #ifdef. */
+
#ifdef NO_PROTOTYPES
-/* In this case we are just duplicating t_float_values, but that is the
- easiest way to deal with either ANSI or non-ANSI. */
-t_float_values2 (float_arg1, float_arg2)
- float float_arg1, float_arg2;
+# define T_VALUES_PARAMS(TYPE) \
+ (arg1, arg2) \
+ TYPE arg1, arg2;
#else
-t_float_values2 (float float_arg1, float float_arg2)
+# define T_VALUES_PARAMS(TYPE) \
+ (TYPE arg1, TYPE arg2)
#endif
-{
- return ((float_arg1 - float_val1) < DELTA
- && (float_arg1 - float_val1) > -DELTA
- && (float_arg2 - float_val2) < DELTA
- && (float_arg2 - float_val2) > -DELTA);
-}
-/* This function has many arguments to force some of them to be passed via
- the stack instead of registers, to test that GDB can construct correctly
- the parameter save area. Note that Linux/ppc32 has 8 float registers to use
- for float parameter passing and Linux/ppc64 has 13, so the number of
- arguments has to be at least 14 to contemplate these platforms. */
+/* Define a function NAME comparing its two TYPE arguments against the
+ TYPE_val1 and TYPE_val2 globals. */
-float
-#ifdef NO_PROTOTYPES
-t_float_many_args (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13,
- f14, f15)
- float f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15;
-#else
-t_float_many_args (float f1, float f2, float f3, float f4, float f5, float f6,
- float f7, float f8, float f9, float f10, float f11,
- float f12, float f13, float f14, float f15)
-#endif
-{
- float sum_args;
- float sum_values;
-
- sum_args = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12
- + f13 + f14 + f15;
- sum_values = float_val1 + float_val2 + float_val3 + float_val4 + float_val5
- + float_val6 + float_val7 + float_val8 + float_val9
- + float_val10 + float_val11 + float_val12 + float_val13
- + float_val14 + float_val15;
-
- return ((sum_args - sum_values) < DELTA
- && (sum_args - sum_values) > -DELTA);
+#define DEFINE_T_FLOAT_VALUES(TYPE, NAME) \
+int \
+NAME T_VALUES_PARAMS (TYPE) \
+{ \
+ return ((arg1 - TYPE##_val1) < DELTA \
+ && (arg1 - TYPE##_val1) > -DELTA \
+ && (arg2 - TYPE##_val2) < DELTA \
+ && (arg2 - TYPE##_val2) > -DELTA); \
}
-#ifdef PROTOTYPES
-int t_double_values (double double_arg1, double double_arg2)
-#else
-int t_double_values (double_arg1, double_arg2)
-double double_arg1, double_arg2;
-#endif
-{
- return ((double_arg1 - double_val1) < DELTA
- && (double_arg1 - double_val1) > -DELTA
- && (double_arg2 - double_val2) < DELTA
- && (double_arg2 - double_val2) > -DELTA);
-}
+DEFINE_T_FLOAT_VALUES (float, t_float_values2)
+DEFINE_T_FLOAT_VALUES (double, t_double_values)
-/* This function has many arguments to force some of them to be passed via
- the stack instead of registers, to test that GDB can construct correctly
- the parameter save area. Note that Linux/ppc32 has 8 float registers to use
- for float parameter passing and Linux/ppc64 has 13, so the number of
- arguments has to be at least 14 to contemplate these platforms. */
+/* The parameter list of a t_TYPE_many_args function. Split out into
+ prototyped vs non-prototyped variants because a macro body cannot
+ contain #ifdef. */
-double
#ifdef NO_PROTOTYPES
-t_double_many_args (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13,
- f14, f15)
- double f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15;
+# define T_MANY_ARGS_PARAMS(TYPE) \
+ (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15) \
+ TYPE f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15;
#else
-t_double_many_args (double f1, double f2, double f3, double f4, double f5,
- double f6, double f7, double f8, double f9, double f10,
- double f11, double f12, double f13, double f14, double f15)
+# define T_MANY_ARGS_PARAMS(TYPE) \
+ (TYPE f1, TYPE f2, TYPE f3, TYPE f4, TYPE f5, TYPE f6, TYPE f7, \
+ TYPE f8, TYPE f9, TYPE f10, TYPE f11, TYPE f12, TYPE f13, TYPE f14, \
+ TYPE f15)
#endif
-{
- double sum_args;
- double sum_values;
-
- sum_args = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12
- + f13 + f14 + f15;
- sum_values = double_val1 + double_val2 + double_val3 + double_val4
- + double_val5 + double_val6 + double_val7 + double_val8
- + double_val9 + double_val10 + double_val11 + double_val12
- + double_val13 + double_val14 + double_val15;
-
- return ((sum_args - sum_values) < DELTA
- && (sum_args - sum_values) > -DELTA);
-}
+
+/* Define a function NAME returning TYPE with many arguments, to force
+ some of them to be passed via the stack instead of registers, to
+ test that GDB can construct the parameter save area correctly.
+ Note that Linux/ppc32 has 8 float registers to use for float
+ parameter passing and Linux/ppc64 has 13, so the number of
+ arguments has to be at least 14 to contemplate these platforms. */
+
+#define DEFINE_T_MANY_ARGS(TYPE, NAME) \
+TYPE \
+NAME T_MANY_ARGS_PARAMS (TYPE) \
+{ \
+ TYPE sum_args; \
+ TYPE sum_values; \
+ \
+ sum_args = (f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 \
+ + f12 + f13 + f14 + f15); \
+ sum_values = (TYPE##_val1 + TYPE##_val2 + TYPE##_val3 \
+ + TYPE##_val4 + TYPE##_val5 + TYPE##_val6 \
+ + TYPE##_val7 + TYPE##_val8 + TYPE##_val9 \
+ + TYPE##_val10 + TYPE##_val11 + TYPE##_val12 \
+ + TYPE##_val13 + TYPE##_val14 + TYPE##_val15); \
+ \
+ return ((sum_args - sum_values) < DELTA \
+ && (sum_args - sum_values) > -DELTA); \
+}
+
+DEFINE_T_MANY_ARGS (float, t_float_many_args)
+DEFINE_T_MANY_ARGS (double, t_double_many_args)
/* Various functions for _Complex types. */
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 3/4] gdb.base/callfuncs.c: factor out float/double functions
2026-07-14 22:06 ` [PATCH 3/4] gdb.base/callfuncs.c: factor out float/double functions Pedro Alves
@ 2026-07-16 21:33 ` Andrew Burgess
0 siblings, 0 replies; 15+ messages in thread
From: Andrew Burgess @ 2026-07-16 21:33 UTC (permalink / raw)
To: Pedro Alves, gdb-patches
Pedro Alves <pedro@palves.net> writes:
> Other than float vs double, t_float_values2 and t_double_values are
> identical. Same for t_float_many_args and t_double_many_args.
>
> Adding 'long double' variants would mean even more duplication.
>
> Factor each "values" and "many_args" pair into a macro that generates
> the function from the type, so that adding a new type is just one
> line.
LGTM.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Thanks,
Andrew
>
> Tested on x86_64-unknown-linux-gnu.
>
> Change-Id: I43013f4db9ccf1e5d8ac17dc5b557bd44500b9f4
> ---
> gdb/testsuite/gdb.base/callfuncs.c | 138 +++++++++++++----------------
> 1 file changed, 60 insertions(+), 78 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.base/callfuncs.c b/gdb/testsuite/gdb.base/callfuncs.c
> index 1d35272a50e..0e6d9dcdd71 100644
> --- a/gdb/testsuite/gdb.base/callfuncs.c
> +++ b/gdb/testsuite/gdb.base/callfuncs.c
> @@ -345,96 +345,78 @@ float float_arg1, float_arg2;
> && (float_arg2 - float_val2) > -DELTA);
> }
>
> -int
> +/* The parameter list of a t_TYPE_values function. Split out into
> + prototyped vs non-prototyped variants because a macro body cannot
> + contain #ifdef. */
> +
> #ifdef NO_PROTOTYPES
> -/* In this case we are just duplicating t_float_values, but that is the
> - easiest way to deal with either ANSI or non-ANSI. */
> -t_float_values2 (float_arg1, float_arg2)
> - float float_arg1, float_arg2;
> +# define T_VALUES_PARAMS(TYPE) \
> + (arg1, arg2) \
> + TYPE arg1, arg2;
> #else
> -t_float_values2 (float float_arg1, float float_arg2)
> +# define T_VALUES_PARAMS(TYPE) \
> + (TYPE arg1, TYPE arg2)
> #endif
> -{
> - return ((float_arg1 - float_val1) < DELTA
> - && (float_arg1 - float_val1) > -DELTA
> - && (float_arg2 - float_val2) < DELTA
> - && (float_arg2 - float_val2) > -DELTA);
> -}
>
> -/* This function has many arguments to force some of them to be passed via
> - the stack instead of registers, to test that GDB can construct correctly
> - the parameter save area. Note that Linux/ppc32 has 8 float registers to use
> - for float parameter passing and Linux/ppc64 has 13, so the number of
> - arguments has to be at least 14 to contemplate these platforms. */
> +/* Define a function NAME comparing its two TYPE arguments against the
> + TYPE_val1 and TYPE_val2 globals. */
>
> -float
> -#ifdef NO_PROTOTYPES
> -t_float_many_args (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13,
> - f14, f15)
> - float f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15;
> -#else
> -t_float_many_args (float f1, float f2, float f3, float f4, float f5, float f6,
> - float f7, float f8, float f9, float f10, float f11,
> - float f12, float f13, float f14, float f15)
> -#endif
> -{
> - float sum_args;
> - float sum_values;
> -
> - sum_args = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12
> - + f13 + f14 + f15;
> - sum_values = float_val1 + float_val2 + float_val3 + float_val4 + float_val5
> - + float_val6 + float_val7 + float_val8 + float_val9
> - + float_val10 + float_val11 + float_val12 + float_val13
> - + float_val14 + float_val15;
> -
> - return ((sum_args - sum_values) < DELTA
> - && (sum_args - sum_values) > -DELTA);
> +#define DEFINE_T_FLOAT_VALUES(TYPE, NAME) \
> +int \
> +NAME T_VALUES_PARAMS (TYPE) \
> +{ \
> + return ((arg1 - TYPE##_val1) < DELTA \
> + && (arg1 - TYPE##_val1) > -DELTA \
> + && (arg2 - TYPE##_val2) < DELTA \
> + && (arg2 - TYPE##_val2) > -DELTA); \
> }
>
> -#ifdef PROTOTYPES
> -int t_double_values (double double_arg1, double double_arg2)
> -#else
> -int t_double_values (double_arg1, double_arg2)
> -double double_arg1, double_arg2;
> -#endif
> -{
> - return ((double_arg1 - double_val1) < DELTA
> - && (double_arg1 - double_val1) > -DELTA
> - && (double_arg2 - double_val2) < DELTA
> - && (double_arg2 - double_val2) > -DELTA);
> -}
> +DEFINE_T_FLOAT_VALUES (float, t_float_values2)
> +DEFINE_T_FLOAT_VALUES (double, t_double_values)
>
> -/* This function has many arguments to force some of them to be passed via
> - the stack instead of registers, to test that GDB can construct correctly
> - the parameter save area. Note that Linux/ppc32 has 8 float registers to use
> - for float parameter passing and Linux/ppc64 has 13, so the number of
> - arguments has to be at least 14 to contemplate these platforms. */
> +/* The parameter list of a t_TYPE_many_args function. Split out into
> + prototyped vs non-prototyped variants because a macro body cannot
> + contain #ifdef. */
>
> -double
> #ifdef NO_PROTOTYPES
> -t_double_many_args (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13,
> - f14, f15)
> - double f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15;
> +# define T_MANY_ARGS_PARAMS(TYPE) \
> + (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15) \
> + TYPE f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15;
> #else
> -t_double_many_args (double f1, double f2, double f3, double f4, double f5,
> - double f6, double f7, double f8, double f9, double f10,
> - double f11, double f12, double f13, double f14, double f15)
> +# define T_MANY_ARGS_PARAMS(TYPE) \
> + (TYPE f1, TYPE f2, TYPE f3, TYPE f4, TYPE f5, TYPE f6, TYPE f7, \
> + TYPE f8, TYPE f9, TYPE f10, TYPE f11, TYPE f12, TYPE f13, TYPE f14, \
> + TYPE f15)
> #endif
> -{
> - double sum_args;
> - double sum_values;
> -
> - sum_args = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12
> - + f13 + f14 + f15;
> - sum_values = double_val1 + double_val2 + double_val3 + double_val4
> - + double_val5 + double_val6 + double_val7 + double_val8
> - + double_val9 + double_val10 + double_val11 + double_val12
> - + double_val13 + double_val14 + double_val15;
> -
> - return ((sum_args - sum_values) < DELTA
> - && (sum_args - sum_values) > -DELTA);
> -}
> +
> +/* Define a function NAME returning TYPE with many arguments, to force
> + some of them to be passed via the stack instead of registers, to
> + test that GDB can construct the parameter save area correctly.
> + Note that Linux/ppc32 has 8 float registers to use for float
> + parameter passing and Linux/ppc64 has 13, so the number of
> + arguments has to be at least 14 to contemplate these platforms. */
> +
> +#define DEFINE_T_MANY_ARGS(TYPE, NAME) \
> +TYPE \
> +NAME T_MANY_ARGS_PARAMS (TYPE) \
> +{ \
> + TYPE sum_args; \
> + TYPE sum_values; \
> + \
> + sum_args = (f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 \
> + + f12 + f13 + f14 + f15); \
> + sum_values = (TYPE##_val1 + TYPE##_val2 + TYPE##_val3 \
> + + TYPE##_val4 + TYPE##_val5 + TYPE##_val6 \
> + + TYPE##_val7 + TYPE##_val8 + TYPE##_val9 \
> + + TYPE##_val10 + TYPE##_val11 + TYPE##_val12 \
> + + TYPE##_val13 + TYPE##_val14 + TYPE##_val15); \
> + \
> + return ((sum_args - sum_values) < DELTA \
> + && (sum_args - sum_values) > -DELTA); \
> +}
> +
> +DEFINE_T_MANY_ARGS (float, t_float_many_args)
> +DEFINE_T_MANY_ARGS (double, t_double_many_args)
>
> /* Various functions for _Complex types. */
>
> --
> 2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 4/4] gdb.base/callfuncs.exp: Exercise "long double"
2026-07-14 22:06 [PATCH 0/4] gdb/testsuite: "long double" infcall tests Pedro Alves
` (2 preceding siblings ...)
2026-07-14 22:06 ` [PATCH 3/4] gdb.base/callfuncs.c: factor out float/double functions Pedro Alves
@ 2026-07-14 22:06 ` Pedro Alves
2026-07-16 21:36 ` Andrew Burgess
2026-07-22 13:01 ` [PATCH 0/4] gdb/testsuite: "long double" infcall tests Pedro Alves
4 siblings, 1 reply; 15+ messages in thread
From: Pedro Alves @ 2026-07-14 22:06 UTC (permalink / raw)
To: gdb-patches
gdb.base/callfuncs.exp tests calling functions that take and return
floating point arguments, but only for float and double. Add long
double too, so that GDB's handling of the type in inferior function
calls is exercised.
On x86_64-pc-windows-msvc, without the fix that teaches GDB about the
correct size of "long double", we get:
$ grep FAIL gdb.sum
FAIL: gdb.base/callfuncs.exp: noproto: p ((int (*) ()) t_long_double_values)(45.654L,-67.66L)
FAIL: gdb.base/callfuncs.exp: p ((int (*) (long double, long double)) t_long_double_values)(45.654,-67.66)
These two tests go through GDB's expression parser for the long double
type. Without the long double fix, GDB is passing 128-bit (amd64
default) but on the MSVC ABI, it should be passing 64-bit.
The other tests pass even without the fix, as those are direct calls
that get the parameter type from DWARF, which has the correct long
double size.
Change-Id: Ibcc3590753d08ece4fbf03c5d890872197047fff
---
gdb/testsuite/gdb.base/callfuncs.c | 58 ++++++++++++++++++++--------
gdb/testsuite/gdb.base/callfuncs.exp | 26 +++++++++++++
2 files changed, 67 insertions(+), 17 deletions(-)
diff --git a/gdb/testsuite/gdb.base/callfuncs.c b/gdb/testsuite/gdb.base/callfuncs.c
index 0e6d9dcdd71..918e8d6f97d 100644
--- a/gdb/testsuite/gdb.base/callfuncs.c
+++ b/gdb/testsuite/gdb.base/callfuncs.c
@@ -72,6 +72,24 @@ double double_val13 = 10.25;
double double_val14 = 11.25;
double double_val15 = 12.25;
+/* "long double" cannot be pasted into a "long_double_val1"
+ identifier, so the long double globals use an "ldouble" prefix. */
+long double ldouble_val1 = 45.654;
+long double ldouble_val2 = -67.66;
+long double ldouble_val3 = 0.25;
+long double ldouble_val4 = 1.25;
+long double ldouble_val5 = 2.25;
+long double ldouble_val6 = 3.25;
+long double ldouble_val7 = 4.25;
+long double ldouble_val8 = 5.25;
+long double ldouble_val9 = 6.25;
+long double ldouble_val10 = 7.25;
+long double ldouble_val11 = 8.25;
+long double ldouble_val12 = 9.25;
+long double ldouble_val13 = 10.25;
+long double ldouble_val14 = 11.25;
+long double ldouble_val15 = 12.25;
+
#ifdef TEST_COMPLEX
extern float crealf (float _Complex);
extern float cimagf (float _Complex);
@@ -359,20 +377,23 @@ float float_arg1, float_arg2;
#endif
/* Define a function NAME comparing its two TYPE arguments against the
- TYPE_val1 and TYPE_val2 globals. */
+ TYPE_val1 and TYPE_val2 globals. PREFIX is passed separately
+ because "long double" cannot be pasted into a "long_double_val1"
+ identifier. */
-#define DEFINE_T_FLOAT_VALUES(TYPE, NAME) \
+#define DEFINE_T_FLOAT_VALUES(TYPE, NAME, PREFIX) \
int \
NAME T_VALUES_PARAMS (TYPE) \
{ \
- return ((arg1 - TYPE##_val1) < DELTA \
- && (arg1 - TYPE##_val1) > -DELTA \
- && (arg2 - TYPE##_val2) < DELTA \
- && (arg2 - TYPE##_val2) > -DELTA); \
+ return ((arg1 - PREFIX##_val1) < DELTA \
+ && (arg1 - PREFIX##_val1) > -DELTA \
+ && (arg2 - PREFIX##_val2) < DELTA \
+ && (arg2 - PREFIX##_val2) > -DELTA); \
}
-DEFINE_T_FLOAT_VALUES (float, t_float_values2)
-DEFINE_T_FLOAT_VALUES (double, t_double_values)
+DEFINE_T_FLOAT_VALUES (float, t_float_values2, float)
+DEFINE_T_FLOAT_VALUES (double, t_double_values, double)
+DEFINE_T_FLOAT_VALUES (long double, t_long_double_values, ldouble)
/* The parameter list of a t_TYPE_many_args function. Split out into
prototyped vs non-prototyped variants because a macro body cannot
@@ -394,9 +415,11 @@ DEFINE_T_FLOAT_VALUES (double, t_double_values)
test that GDB can construct the parameter save area correctly.
Note that Linux/ppc32 has 8 float registers to use for float
parameter passing and Linux/ppc64 has 13, so the number of
- arguments has to be at least 14 to contemplate these platforms. */
+ arguments has to be at least 14 to contemplate these platforms.
+ PREFIX is passed separately because "long double" cannot be pasted
+ into a "long_double_val1" identifier. */
-#define DEFINE_T_MANY_ARGS(TYPE, NAME) \
+#define DEFINE_T_MANY_ARGS(TYPE, NAME, PREFIX) \
TYPE \
NAME T_MANY_ARGS_PARAMS (TYPE) \
{ \
@@ -405,18 +428,19 @@ NAME T_MANY_ARGS_PARAMS (TYPE) \
\
sum_args = (f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 \
+ f12 + f13 + f14 + f15); \
- sum_values = (TYPE##_val1 + TYPE##_val2 + TYPE##_val3 \
- + TYPE##_val4 + TYPE##_val5 + TYPE##_val6 \
- + TYPE##_val7 + TYPE##_val8 + TYPE##_val9 \
- + TYPE##_val10 + TYPE##_val11 + TYPE##_val12 \
- + TYPE##_val13 + TYPE##_val14 + TYPE##_val15); \
+ sum_values = (PREFIX##_val1 + PREFIX##_val2 + PREFIX##_val3 \
+ + PREFIX##_val4 + PREFIX##_val5 + PREFIX##_val6 \
+ + PREFIX##_val7 + PREFIX##_val8 + PREFIX##_val9 \
+ + PREFIX##_val10 + PREFIX##_val11 + PREFIX##_val12 \
+ + PREFIX##_val13 + PREFIX##_val14 + PREFIX##_val15); \
\
return ((sum_args - sum_values) < DELTA \
&& (sum_args - sum_values) > -DELTA); \
}
-DEFINE_T_MANY_ARGS (float, t_float_many_args)
-DEFINE_T_MANY_ARGS (double, t_double_many_args)
+DEFINE_T_MANY_ARGS (float, t_float_many_args, float)
+DEFINE_T_MANY_ARGS (double, t_double_many_args, double)
+DEFINE_T_MANY_ARGS (long double, t_long_double_many_args, ldouble)
/* Various functions for _Complex types. */
diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp
index f020100ce8b..ebc389c6b03 100644
--- a/gdb/testsuite/gdb.base/callfuncs.exp
+++ b/gdb/testsuite/gdb.base/callfuncs.exp
@@ -136,6 +136,32 @@ proc do_function_calls {prototypes} {
gdb_test "p t_double_many_args (double_val1, double_val2, double_val3, double_val4, double_val5, double_val6, double_val7, double_val8, double_val9, double_val10, double_val11, double_val12, double_val13, double_val14, double_val15)" " = 1" "call function with many double arguments."
+ gdb_test "p t_long_double_values(0.0,0.0)" " = 0"
+ # Same, via function pointer. When the pointer type is
+ # unprototyped, GDB has no parameter type to coerce the
+ # arguments to, so the literals must carry the "L" suffix to
+ # be passed as long double rather than double.
+ if {$prototypes} {
+ gdb_test "p ((int (*) (long double, long double)) t_long_double_values)(0.0,0.0)" " = 0"
+ } else {
+ gdb_test "p ((int (*) ()) t_long_double_values)(0.0L,0.0L)" " = 0"
+ }
+
+ gdb_test "p t_long_double_values(45.654,-67.66)" " = 1"
+ if {$prototypes} {
+ gdb_test "p ((int (*) (long double, long double)) t_long_double_values)(45.654,-67.66)" " = 1"
+ } else {
+ gdb_test "p ((int (*) ()) t_long_double_values)(45.654L,-67.66L)" " = 1"
+ }
+
+ gdb_test "p t_long_double_values(ldouble_val1,ldouble_val2)" " = 1"
+ gdb_test "p t_long_double_values(45.654,ldouble_val2)" " = 1"
+ gdb_test "p t_long_double_values(ldouble_val1,-67.66)" " = 1"
+
+ gdb_test "p t_long_double_many_args (ldouble_val1, ldouble_val2, ldouble_val3, ldouble_val4, ldouble_val5, ldouble_val6, ldouble_val7, ldouble_val8, ldouble_val9, ldouble_val10, ldouble_val11, ldouble_val12, ldouble_val13, ldouble_val14, ldouble_val15)" \
+ " = 1" \
+ "call function with many long double arguments"
+
gdb_test "p t_double_int(99.0, 1)" " = 0"
gdb_test "p t_double_int(99.0, 99)" " = 1"
gdb_test "p t_int_double(99, 1.0)" " = 0"
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 4/4] gdb.base/callfuncs.exp: Exercise "long double"
2026-07-14 22:06 ` [PATCH 4/4] gdb.base/callfuncs.exp: Exercise "long double" Pedro Alves
@ 2026-07-16 21:36 ` Andrew Burgess
0 siblings, 0 replies; 15+ messages in thread
From: Andrew Burgess @ 2026-07-16 21:36 UTC (permalink / raw)
To: Pedro Alves, gdb-patches
Pedro Alves <pedro@palves.net> writes:
> gdb.base/callfuncs.exp tests calling functions that take and return
> floating point arguments, but only for float and double. Add long
> double too, so that GDB's handling of the type in inferior function
> calls is exercised.
>
> On x86_64-pc-windows-msvc, without the fix that teaches GDB about the
> correct size of "long double", we get:
>
> $ grep FAIL gdb.sum
> FAIL: gdb.base/callfuncs.exp: noproto: p ((int (*) ()) t_long_double_values)(45.654L,-67.66L)
> FAIL: gdb.base/callfuncs.exp: p ((int (*) (long double, long double)) t_long_double_values)(45.654,-67.66)
>
> These two tests go through GDB's expression parser for the long double
> type. Without the long double fix, GDB is passing 128-bit (amd64
> default) but on the MSVC ABI, it should be passing 64-bit.
>
> The other tests pass even without the fix, as those are direct calls
> that get the parameter type from DWARF, which has the correct long
> double size.
LGTM.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Thanks,
Andrew
>
> Change-Id: Ibcc3590753d08ece4fbf03c5d890872197047fff
> ---
> gdb/testsuite/gdb.base/callfuncs.c | 58 ++++++++++++++++++++--------
> gdb/testsuite/gdb.base/callfuncs.exp | 26 +++++++++++++
> 2 files changed, 67 insertions(+), 17 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.base/callfuncs.c b/gdb/testsuite/gdb.base/callfuncs.c
> index 0e6d9dcdd71..918e8d6f97d 100644
> --- a/gdb/testsuite/gdb.base/callfuncs.c
> +++ b/gdb/testsuite/gdb.base/callfuncs.c
> @@ -72,6 +72,24 @@ double double_val13 = 10.25;
> double double_val14 = 11.25;
> double double_val15 = 12.25;
>
> +/* "long double" cannot be pasted into a "long_double_val1"
> + identifier, so the long double globals use an "ldouble" prefix. */
> +long double ldouble_val1 = 45.654;
> +long double ldouble_val2 = -67.66;
> +long double ldouble_val3 = 0.25;
> +long double ldouble_val4 = 1.25;
> +long double ldouble_val5 = 2.25;
> +long double ldouble_val6 = 3.25;
> +long double ldouble_val7 = 4.25;
> +long double ldouble_val8 = 5.25;
> +long double ldouble_val9 = 6.25;
> +long double ldouble_val10 = 7.25;
> +long double ldouble_val11 = 8.25;
> +long double ldouble_val12 = 9.25;
> +long double ldouble_val13 = 10.25;
> +long double ldouble_val14 = 11.25;
> +long double ldouble_val15 = 12.25;
> +
> #ifdef TEST_COMPLEX
> extern float crealf (float _Complex);
> extern float cimagf (float _Complex);
> @@ -359,20 +377,23 @@ float float_arg1, float_arg2;
> #endif
>
> /* Define a function NAME comparing its two TYPE arguments against the
> - TYPE_val1 and TYPE_val2 globals. */
> + TYPE_val1 and TYPE_val2 globals. PREFIX is passed separately
> + because "long double" cannot be pasted into a "long_double_val1"
> + identifier. */
>
> -#define DEFINE_T_FLOAT_VALUES(TYPE, NAME) \
> +#define DEFINE_T_FLOAT_VALUES(TYPE, NAME, PREFIX) \
> int \
> NAME T_VALUES_PARAMS (TYPE) \
> { \
> - return ((arg1 - TYPE##_val1) < DELTA \
> - && (arg1 - TYPE##_val1) > -DELTA \
> - && (arg2 - TYPE##_val2) < DELTA \
> - && (arg2 - TYPE##_val2) > -DELTA); \
> + return ((arg1 - PREFIX##_val1) < DELTA \
> + && (arg1 - PREFIX##_val1) > -DELTA \
> + && (arg2 - PREFIX##_val2) < DELTA \
> + && (arg2 - PREFIX##_val2) > -DELTA); \
> }
>
> -DEFINE_T_FLOAT_VALUES (float, t_float_values2)
> -DEFINE_T_FLOAT_VALUES (double, t_double_values)
> +DEFINE_T_FLOAT_VALUES (float, t_float_values2, float)
> +DEFINE_T_FLOAT_VALUES (double, t_double_values, double)
> +DEFINE_T_FLOAT_VALUES (long double, t_long_double_values, ldouble)
>
> /* The parameter list of a t_TYPE_many_args function. Split out into
> prototyped vs non-prototyped variants because a macro body cannot
> @@ -394,9 +415,11 @@ DEFINE_T_FLOAT_VALUES (double, t_double_values)
> test that GDB can construct the parameter save area correctly.
> Note that Linux/ppc32 has 8 float registers to use for float
> parameter passing and Linux/ppc64 has 13, so the number of
> - arguments has to be at least 14 to contemplate these platforms. */
> + arguments has to be at least 14 to contemplate these platforms.
> + PREFIX is passed separately because "long double" cannot be pasted
> + into a "long_double_val1" identifier. */
>
> -#define DEFINE_T_MANY_ARGS(TYPE, NAME) \
> +#define DEFINE_T_MANY_ARGS(TYPE, NAME, PREFIX) \
> TYPE \
> NAME T_MANY_ARGS_PARAMS (TYPE) \
> { \
> @@ -405,18 +428,19 @@ NAME T_MANY_ARGS_PARAMS (TYPE) \
> \
> sum_args = (f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 \
> + f12 + f13 + f14 + f15); \
> - sum_values = (TYPE##_val1 + TYPE##_val2 + TYPE##_val3 \
> - + TYPE##_val4 + TYPE##_val5 + TYPE##_val6 \
> - + TYPE##_val7 + TYPE##_val8 + TYPE##_val9 \
> - + TYPE##_val10 + TYPE##_val11 + TYPE##_val12 \
> - + TYPE##_val13 + TYPE##_val14 + TYPE##_val15); \
> + sum_values = (PREFIX##_val1 + PREFIX##_val2 + PREFIX##_val3 \
> + + PREFIX##_val4 + PREFIX##_val5 + PREFIX##_val6 \
> + + PREFIX##_val7 + PREFIX##_val8 + PREFIX##_val9 \
> + + PREFIX##_val10 + PREFIX##_val11 + PREFIX##_val12 \
> + + PREFIX##_val13 + PREFIX##_val14 + PREFIX##_val15); \
> \
> return ((sum_args - sum_values) < DELTA \
> && (sum_args - sum_values) > -DELTA); \
> }
>
> -DEFINE_T_MANY_ARGS (float, t_float_many_args)
> -DEFINE_T_MANY_ARGS (double, t_double_many_args)
> +DEFINE_T_MANY_ARGS (float, t_float_many_args, float)
> +DEFINE_T_MANY_ARGS (double, t_double_many_args, double)
> +DEFINE_T_MANY_ARGS (long double, t_long_double_many_args, ldouble)
>
> /* Various functions for _Complex types. */
>
> diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp
> index f020100ce8b..ebc389c6b03 100644
> --- a/gdb/testsuite/gdb.base/callfuncs.exp
> +++ b/gdb/testsuite/gdb.base/callfuncs.exp
> @@ -136,6 +136,32 @@ proc do_function_calls {prototypes} {
>
> gdb_test "p t_double_many_args (double_val1, double_val2, double_val3, double_val4, double_val5, double_val6, double_val7, double_val8, double_val9, double_val10, double_val11, double_val12, double_val13, double_val14, double_val15)" " = 1" "call function with many double arguments."
>
> + gdb_test "p t_long_double_values(0.0,0.0)" " = 0"
> + # Same, via function pointer. When the pointer type is
> + # unprototyped, GDB has no parameter type to coerce the
> + # arguments to, so the literals must carry the "L" suffix to
> + # be passed as long double rather than double.
> + if {$prototypes} {
> + gdb_test "p ((int (*) (long double, long double)) t_long_double_values)(0.0,0.0)" " = 0"
> + } else {
> + gdb_test "p ((int (*) ()) t_long_double_values)(0.0L,0.0L)" " = 0"
> + }
> +
> + gdb_test "p t_long_double_values(45.654,-67.66)" " = 1"
> + if {$prototypes} {
> + gdb_test "p ((int (*) (long double, long double)) t_long_double_values)(45.654,-67.66)" " = 1"
> + } else {
> + gdb_test "p ((int (*) ()) t_long_double_values)(45.654L,-67.66L)" " = 1"
> + }
> +
> + gdb_test "p t_long_double_values(ldouble_val1,ldouble_val2)" " = 1"
> + gdb_test "p t_long_double_values(45.654,ldouble_val2)" " = 1"
> + gdb_test "p t_long_double_values(ldouble_val1,-67.66)" " = 1"
> +
> + gdb_test "p t_long_double_many_args (ldouble_val1, ldouble_val2, ldouble_val3, ldouble_val4, ldouble_val5, ldouble_val6, ldouble_val7, ldouble_val8, ldouble_val9, ldouble_val10, ldouble_val11, ldouble_val12, ldouble_val13, ldouble_val14, ldouble_val15)" \
> + " = 1" \
> + "call function with many long double arguments"
> +
> gdb_test "p t_double_int(99.0, 1)" " = 0"
> gdb_test "p t_double_int(99.0, 99)" " = 1"
> gdb_test "p t_int_double(99, 1.0)" " = 0"
> --
> 2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 0/4] gdb/testsuite: "long double" infcall tests
2026-07-14 22:06 [PATCH 0/4] gdb/testsuite: "long double" infcall tests Pedro Alves
` (3 preceding siblings ...)
2026-07-14 22:06 ` [PATCH 4/4] gdb.base/callfuncs.exp: Exercise "long double" Pedro Alves
@ 2026-07-22 13:01 ` Pedro Alves
4 siblings, 0 replies; 15+ messages in thread
From: Pedro Alves @ 2026-07-22 13:01 UTC (permalink / raw)
To: gdb-patches
FYI, I pushed this.
On 2026-07-14 23:06, Pedro Alves wrote:
> This series adds coverage for calling functions with long double in
> their arguments, in cases where the "long double" type comes from
> GDB's own built-in type, not debug info. These tests expose the need
> for GDB knowing that "long double" is 64-bit on windows-msvc. See:
>
> [PATCH 0/4] Support the Windows/MSVC target in GDB
> https://inbox.sourceware.org/gdb-patches/20260714004507.1323332-1-pedro@palves.net/T/
>
> These new tests fail on x86_64-pc-windows-msvc with unfixed GDB, and
> pass cleanly with a fixed GDB. I don't have Aarch64 to test, but I
> expect it's the same there.
>
> Pedro Alves (4):
> gdb.base/nodebug.exp: Add long double testing
> gdb.base/callfuncs.exp: Adjust for Windows
> gdb.base/callfuncs.c: factor out float/double functions
> gdb.base/callfuncs.exp: Exercise "long double"
>
> gdb/testsuite/gdb.base/callfuncs.c | 166 ++++++++++++++-------------
> gdb/testsuite/gdb.base/callfuncs.exp | 52 +++++++--
> gdb/testsuite/gdb.base/nodebug.c | 13 +++
> gdb/testsuite/gdb.base/nodebug.exp | 6 +
> 4 files changed, 145 insertions(+), 92 deletions(-)
>
>
> base-commit: 490469846dcef89fe53668bdbba73591c64bed61
^ permalink raw reply [flat|nested] 15+ messages in thread