On 1/9/25 8:25 AM, Simon Martin wrote:
We segfault upon the following invalid code

=== cut here ===
template <int> struct S {
   friend void foo (int a = []{}());
};
void foo (int a) {}
int main () {
   S<0> t;
   foo ();
}
=== cut here ===

The problem is that we end up with a LAMBDA_EXPR callee in
set_flags_from_callee, and dereference its NULL_TREE
TREE_TYPE (TREE_TYPE ( )).

This patch simply sets the default argument to error_mark_node for
friend functions that do not meet the requirement in C++17 11.3.6/4.

Successfully tested on x86_64-pc-linux-gnu.

        PR c++/118319

gcc/cp/ChangeLog:

        * decl.cc (grokfndecl): Inspect all friend function parameters,
        and set them to error_mark_node if invalid.

gcc/testsuite/ChangeLog:

        * g++.dg/parse/defarg18.C: New test.

---
  gcc/cp/decl.cc                        | 13 +++++---
  gcc/testsuite/g++.dg/parse/defarg18.C | 48 +++++++++++++++++++++++++++
  2 files changed, 57 insertions(+), 4 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/parse/defarg18.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 503ecd9387e..b2761c23d3e 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -11134,14 +11134,19 @@ grokfndecl (tree ctype,
       expression, that declaration shall be a definition..."  */
    if (friendp && !funcdef_flag)
      {
+      bool has_permerrored = false;
        for (tree t = FUNCTION_FIRST_USER_PARMTYPE (decl);
           t && t != void_list_node; t = TREE_CHAIN (t))
        if (TREE_PURPOSE (t))
          {
-           permerror (DECL_SOURCE_LOCATION (decl),
-                      "friend declaration of %qD specifies default "
-                      "arguments and isn%'t a definition", decl);
-           break;
+           if (!has_permerrored)
+             {
+               has_permerrored = true;
+               permerror (DECL_SOURCE_LOCATION (decl),
+                          "friend declaration of %qD specifies default "
+                          "arguments and isn%'t a definition", decl);
+             }
+           TREE_PURPOSE (t) = error_mark_node;

If we're going to unconditionally change TREE_PURPOSE, then permerror needs to strengthen to error. But I'd think we could leave the current state in a non-template class, only changing the template case.

Jason

Reply via email to