https://gcc.gnu.org/g:9971faf312bfa502d8c983b528f80e4538cfefaf

commit r17-3994-g9971faf312bfa502d8c983b528f80e4538cfefaf
Author: Lunex <[email protected]>
Date:   Fri Sep 4 18:26:35 2026 +0600

    c++: friend with explicit object parameter [PR122258]
    
    A friend which is not a member but 'this Self &&' was used on that that
    is only for members. GCC failed to check and later it crashed with no access
    info to check.
    
    Now we just reject only [non-member]friend that uses an explicit object
    parameter.
    
            PR c++/122258
    
    gcc/cp/ChangeLog:
    
            * decl.cc (grokdeclarator): Extend non-member explicit object
            parameter check to include unqualified friends and clear
            is_xobj_member_function.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp23/explicit-obj-diagnostics13.C: New test.
    
    Co-authored-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/decl.cc                                     | 11 ++--
 .../g++.dg/cpp23/explicit-obj-diagnostics13.C      | 66 ++++++++++++++++++++++
 2 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 6e45321e9710..ff8e3fd2119f 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -15678,12 +15678,15 @@ grokdeclarator (const cp_declarator *declarator,
            if (xobj_parm)
              {
                if (!ctype
-                   && decl_context == NORMAL
+                   && (decl_context == NORMAL || friendp)
                    && (in_namespace
                        || !declarator->declarator->u.id.qualifying_scope))
-                 error_at (DECL_SOURCE_LOCATION (xobj_parm),
-                           "a non-member function cannot have "
-                           "an explicit object parameter");
+                 {
+                   error_at (DECL_SOURCE_LOCATION (xobj_parm),
+                             "a non-member function cannot have "
+                             "an explicit object parameter");
+                   is_xobj_member_function = false;
+                 }
                else
                  {
                    if (virtualp)
diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics13.C 
b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics13.C
new file mode 100644
index 000000000000..00f55cbfc9de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics13.C
@@ -0,0 +1,66 @@
+// P0847R7
+// { dg-do compile { target c++23 } }
+
+namespace std {
+  template<typename T> struct tuple_size;
+  template<int, typename> struct tuple_element;
+}
+
+// PR c++/122258 - friend with explicit object param must be rejected
+
+struct type {
+  template<unsigned I, class Self>
+  friend auto get(this Self &&self) { return 0; } // { dg-error "a non-member 
function cannot have an explicit object parameter" }
+};
+
+struct S {
+  friend void f(this S &); // { dg-error "a non-member function cannot have an 
explicit object parameter" }
+  friend void g(this S &&); // { dg-error "a non-member function cannot have 
an explicit object parameter" }
+};
+
+struct U {
+  template<class Self>
+  friend void h(this Self &&); // { dg-error "a non-member function cannot 
have an explicit object parameter" }
+  template<class Self>
+  friend void k(this Self &&) {} // { dg-error "a non-member function cannot 
have an explicit object parameter" }
+};
+
+struct V {
+  friend void m(this V &) {} // { dg-error "a non-member function cannot have 
an explicit object parameter" }
+};
+
+struct Mem {
+  void mem(this Mem&);
+};
+
+struct A {
+  friend void Mem::mem(this Mem&);
+};
+
+struct B {
+  friend void Mem::mem(this Mem&);
+};
+
+struct C {
+  friend void Mem::mem(this Mem&);
+};
+
+namespace std {
+template<> struct tuple_size<type> { static const int value = 1; };
+template<int I> struct tuple_element<I, type> { using type = int; };
+}
+
+void test_sb()
+{
+  auto [a] = type();
+}
+
+void test_friend_member(void)
+{
+  struct Mem2 {
+    void mem(this Mem2&);
+  };
+  struct A {
+    friend void Mem2::mem(this Mem2&);
+  };
+}

Reply via email to