c++: Fix lambdas with variadic parameters and static specifier [PR119048]

Message ID bf577133-ed7c-40ce-8450-b275662f816e@gmail.com
State New
Headers
Series c++: Fix lambdas with variadic parameters and static specifier [PR119048] |

Commit Message

Eczbek Sept. 16, 2025, 12:43 a.m. UTC
  From d70ac2b0a7b524829d22b3bb6bacbe1ef381c7fb Mon Sep 17 00:00:00 2001
From: Eczbek <eczbek.void@gmail.com>
Date: Mon, 15 Sep 2025 19:37:20 -0400
Subject: [PATCH] c++: Fix lambdas with variadic parameters and static
  specifier [PR119048]

	PR c++/119048

gcc/cp/ChangeLog:

	* lambda.cc (compare_lambda_sig): Only skip first parameter for
	object members.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp23/static-operator-call8.C: New test.

Signed-off-by: Eczbek <eczbek.void@gmail.com>
---
  gcc/cp/lambda.cc                                   | 12 ++++++++----
  gcc/testsuite/g++.dg/cpp23/static-operator-call8.C |  6 ++++++
  2 files changed, 14 insertions(+), 4 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
  

Comments

Patrick Palka Sept. 18, 2025, 7:57 p.m. UTC | #1
On Mon, 15 Sep 2025, Eczbek wrote:

> From d70ac2b0a7b524829d22b3bb6bacbe1ef381c7fb Mon Sep 17 00:00:00 2001
> From: Eczbek <eczbek.void@gmail.com>
> Date: Mon, 15 Sep 2025 19:37:20 -0400
> Subject: [PATCH] c++: Fix lambdas with variadic parameters and static
>  specifier [PR119048]
> 
> 	PR c++/119048
> 
> gcc/cp/ChangeLog:
> 
> 	* lambda.cc (compare_lambda_sig): Only skip first parameter for
> 	object members.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp23/static-operator-call8.C: New test.
> 
> Signed-off-by: Eczbek <eczbek.void@gmail.com>
> ---
>  gcc/cp/lambda.cc                                   | 12 ++++++++----
>  gcc/testsuite/g++.dg/cpp23/static-operator-call8.C |  6 ++++++
>  2 files changed, 14 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
> 
> diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
> index 711e3b7a18e..8950404ae1d 100644
> --- a/gcc/cp/lambda.cc
> +++ b/gcc/cp/lambda.cc
> @@ -1742,10 +1742,14 @@ compare_lambda_sig (tree fn_a, tree fn_b)
>        || fn_b == error_mark_node)
>      return false;
> 
> -  for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
> -	 args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
> -       args_a || args_b;
> -       args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
> +  tree args_a = TYPE_ARG_TYPES (TREE_TYPE (fn_a));
> +  if (DECL_OBJECT_MEMBER_FUNCTION_P (fn_a))
> +      args_a = TREE_CHAIN (args_a);

Thanks for the patch!

This definitely seems like an improvement to the current buggy code, but
I think we really only want to skip implicit object parameters since we
should consider explicit object parameters part of the lambda signature
and thus compare them.  Does checking DECL_IOBJ_MEMBER_FUNCTION_P
instead work?

> +  tree args_b = TYPE_ARG_TYPES (TREE_TYPE (fn_b));
> +  if (DECL_OBJECT_MEMBER_FUNCTION_P (fn_b))
> +      args_b = TREE_CHAIN (args_b);
> +  for (; args_a || args_b;
> +     args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
>      {
>        if (!args_a || !args_b)
>  	return false;
> diff --git a/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
> b/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
> new file mode 100644
> index 00000000000..46aa6b42ce8
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
> @@ -0,0 +1,6 @@
> +// PR c++/119048
> +// { dg-do compile { target c++23 } }
> +
> +int main() {
> +	[] {}, [](...) static {};
> +}
> -- 
> 2.51.0
> 
>
  
Jason Merrill Sept. 19, 2025, 12:51 p.m. UTC | #2
On 9/18/25 9:57 PM, Patrick Palka wrote:
> On Mon, 15 Sep 2025, Eczbek wrote:
> 
>>  From d70ac2b0a7b524829d22b3bb6bacbe1ef381c7fb Mon Sep 17 00:00:00 2001
>> From: Eczbek <eczbek.void@gmail.com>
>> Date: Mon, 15 Sep 2025 19:37:20 -0400
>> Subject: [PATCH] c++: Fix lambdas with variadic parameters and static
>>   specifier [PR119048]
>>
>> 	PR c++/119048
>>
>> gcc/cp/ChangeLog:
>>
>> 	* lambda.cc (compare_lambda_sig): Only skip first parameter for
>> 	object members.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* g++.dg/cpp23/static-operator-call8.C: New test.
>>
>> Signed-off-by: Eczbek <eczbek.void@gmail.com>
>> ---
>>   gcc/cp/lambda.cc                                   | 12 ++++++++----
>>   gcc/testsuite/g++.dg/cpp23/static-operator-call8.C |  6 ++++++
>>   2 files changed, 14 insertions(+), 4 deletions(-)
>>   create mode 100644 gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
>>
>> diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
>> index 711e3b7a18e..8950404ae1d 100644
>> --- a/gcc/cp/lambda.cc
>> +++ b/gcc/cp/lambda.cc
>> @@ -1742,10 +1742,14 @@ compare_lambda_sig (tree fn_a, tree fn_b)
>>         || fn_b == error_mark_node)
>>       return false;
>>
>> -  for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
>> -	 args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
>> -       args_a || args_b;
>> -       args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
>> +  tree args_a = TYPE_ARG_TYPES (TREE_TYPE (fn_a));
>> +  if (DECL_OBJECT_MEMBER_FUNCTION_P (fn_a))
>> +      args_a = TREE_CHAIN (args_a);
> 
> Thanks for the patch!
> 
> This definitely seems like an improvement to the current buggy code, but
> I think we really only want to skip implicit object parameters since we
> should consider explicit object parameters part of the lambda signature
> and thus compare them.  Does checking DECL_IOBJ_MEMBER_FUNCTION_P
> instead work?

Or shorten to FUNCTION_FIRST_USER_PARMTYPE (fn_[ab]).

Jason
  
Eczbek Sept. 20, 2025, 1:25 p.m. UTC | #3
On 9/19/25 8:51 AM, Jason Merrill wrote:
> On 9/18/25 9:57 PM, Patrick Palka wrote:
>> On Mon, 15 Sep 2025, Eczbek wrote:
>>
>>>  From d70ac2b0a7b524829d22b3bb6bacbe1ef381c7fb Mon Sep 17 00:00:00 2001
>>> From: Eczbek <eczbek.void@gmail.com>
>>> Date: Mon, 15 Sep 2025 19:37:20 -0400
>>> Subject: [PATCH] c++: Fix lambdas with variadic parameters and static
>>>   specifier [PR119048]
>>>
>>>     PR c++/119048
>>>
>>> gcc/cp/ChangeLog:
>>>
>>>     * lambda.cc (compare_lambda_sig): Only skip first parameter for
>>>     object members.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>>     * g++.dg/cpp23/static-operator-call8.C: New test.
>>>
>>> Signed-off-by: Eczbek <eczbek.void@gmail.com>
>>> ---
>>>   gcc/cp/lambda.cc                                   | 12 ++++++++----
>>>   gcc/testsuite/g++.dg/cpp23/static-operator-call8.C |  6 ++++++
>>>   2 files changed, 14 insertions(+), 4 deletions(-)
>>>   create mode 100644 gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
>>>
>>> diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
>>> index 711e3b7a18e..8950404ae1d 100644
>>> --- a/gcc/cp/lambda.cc
>>> +++ b/gcc/cp/lambda.cc
>>> @@ -1742,10 +1742,14 @@ compare_lambda_sig (tree fn_a, tree fn_b)
>>>         || fn_b == error_mark_node)
>>>       return false;
>>>
>>> -  for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
>>> -     args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
>>> -       args_a || args_b;
>>> -       args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
>>> +  tree args_a = TYPE_ARG_TYPES (TREE_TYPE (fn_a));
>>> +  if (DECL_OBJECT_MEMBER_FUNCTION_P (fn_a))
>>> +      args_a = TREE_CHAIN (args_a);
>>
>> Thanks for the patch!
>>
>> This definitely seems like an improvement to the current buggy code, but
>> I think we really only want to skip implicit object parameters since we
>> should consider explicit object parameters part of the lambda signature
>> and thus compare them.  Does checking DECL_IOBJ_MEMBER_FUNCTION_P
>> instead work?
> 
> Or shorten to FUNCTION_FIRST_USER_PARMTYPE (fn_[ab]).
> 
> Jason

Thanks!

-- >8 --

 From d4613869df103ba461ca268c8a803ad529f479ba Mon Sep 17 00:00:00 2001
From: Eczbek <eczbek.void@gmail.com>
Date: Sat, 20 Sep 2025 08:58:00 -0400
Subject: [PATCH] c++: Fix lambdas with variadic parameters and static
  specifier [PR119048]

	PR c++/119048

gcc/cp/ChangeLog:

	* lambda.cc (compare_lambda_sig): Only skip first parameter for
	object members.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp23/static-operator-call8.C: New test.

Signed-off-by: Eczbek <eczbek.void@gmail.com>
---
  gcc/cp/lambda.cc                                   | 4 ++--
  gcc/testsuite/g++.dg/cpp23/static-operator-call8.C | 6 ++++++
  2 files changed, 8 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp23/static-operator-call8.C

diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index 711e3b7a18e..bb0aa7d0a02 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1742,8 +1742,8 @@ compare_lambda_sig (tree fn_a, tree fn_b)
        || fn_b == error_mark_node)
      return false;

-  for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
-	 args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
+  for (tree args_a = FUNCTION_FIRST_USER_PARMTYPE (fn_a),
+	 args_b = FUNCTION_FIRST_USER_PARMTYPE (fn_b);
         args_a || args_b;
         args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
      {
diff --git a/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C 
b/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
new file mode 100644
index 00000000000..46aa6b42ce8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
@@ -0,0 +1,6 @@
+// PR c++/119048
+// { dg-do compile { target c++23 } }
+
+int main() {
+	[] {}, [](...) static {};
+}
  
Jason Merrill Sept. 20, 2025, 2:32 p.m. UTC | #4
On 9/20/25 2:25 PM, Eczbek wrote:
>> Or shorten to FUNCTION_FIRST_USER_PARMTYPE (fn_[ab]).
>>
>> Jason
> 
> Thanks!
> 
> -- >8 --
> 
>  From d4613869df103ba461ca268c8a803ad529f479ba Mon Sep 17 00:00:00 2001
> From: Eczbek <eczbek.void@gmail.com>
> Date: Sat, 20 Sep 2025 08:58:00 -0400
> Subject: [PATCH] c++: Fix lambdas with variadic parameters and static
>   specifier [PR119048]
> 
>      PR c++/119048
> 
> gcc/cp/ChangeLog:
> 
>      * lambda.cc (compare_lambda_sig): Only skip first parameter for
>      object members.
> 
> gcc/testsuite/ChangeLog:
> 
>      * g++.dg/cpp23/static-operator-call8.C: New test.
> 
> Signed-off-by: Eczbek <eczbek.void@gmail.com>

Applied, thanks!

I'm not familiar with this identity, so I can't accept the 
Signed-off-by, but the change is small enough to be insignificant for 
copyright so I pushed it on that basis.

If you want to contribute larger patches under a pseudonym that isn't 
known in the GCC community, please file a copyright assignment with the FSF.

https://gcc.gnu.org/contribute.html#legal

Thanks again,
Jason

> ---
>   gcc/cp/lambda.cc                                   | 4 ++--
>   gcc/testsuite/g++.dg/cpp23/static-operator-call8.C | 6 ++++++
>   2 files changed, 8 insertions(+), 2 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
> 
> diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
> index 711e3b7a18e..bb0aa7d0a02 100644
> --- a/gcc/cp/lambda.cc
> +++ b/gcc/cp/lambda.cc
> @@ -1742,8 +1742,8 @@ compare_lambda_sig (tree fn_a, tree fn_b)
>         || fn_b == error_mark_node)
>       return false;
> 
> -  for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
> -     args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
> +  for (tree args_a = FUNCTION_FIRST_USER_PARMTYPE (fn_a),
> +     args_b = FUNCTION_FIRST_USER_PARMTYPE (fn_b);
>          args_a || args_b;
>          args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
>       {
> diff --git a/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C b/gcc/ 
> testsuite/g++.dg/cpp23/static-operator-call8.C
> new file mode 100644
> index 00000000000..46aa6b42ce8
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
> @@ -0,0 +1,6 @@
> +// PR c++/119048
> +// { dg-do compile { target c++23 } }
> +
> +int main() {
> +    [] {}, [](...) static {};
> +}
  

Patch

diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index 711e3b7a18e..8950404ae1d 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1742,10 +1742,14 @@  compare_lambda_sig (tree fn_a, tree fn_b)
        || fn_b == error_mark_node)
      return false;

-  for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
-	 args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
-       args_a || args_b;
-       args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
+  tree args_a = TYPE_ARG_TYPES (TREE_TYPE (fn_a));
+  if (DECL_OBJECT_MEMBER_FUNCTION_P (fn_a))
+      args_a = TREE_CHAIN (args_a);
+  tree args_b = TYPE_ARG_TYPES (TREE_TYPE (fn_b));
+  if (DECL_OBJECT_MEMBER_FUNCTION_P (fn_b))
+      args_b = TREE_CHAIN (args_b);
+  for (; args_a || args_b;
+     args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
      {
        if (!args_a || !args_b)
  	return false;
diff --git a/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C 
b/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
new file mode 100644
index 00000000000..46aa6b42ce8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/static-operator-call8.C
@@ -0,0 +1,6 @@ 
+// PR c++/119048
+// { dg-do compile { target c++23 } }
+
+int main() {
+	[] {}, [](...) static {};
+}