public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-465] c++: hidden friend access [DR1699]
@ 2022-05-15 16:45 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2022-05-15 16:45 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:4df735e01e319997841574f353d2aa076a0335c2

commit r13-465-g4df735e01e319997841574f353d2aa076a0335c2
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Mar 18 22:52:32 2022 -0400

    c++: hidden friend access [DR1699]
    
    It has come up several times that Clang considers hidden friends of a class
    to be sufficiently memberly to be covered by a friend declaration naming the
    class.  This is somewhat unclear in the standard: [class.friend] says
    "Declaring a class to be a friend implies that private and protected members
    of the class granting friendship can be named in the base-specifiers and
    member declarations of the befriended class."
    
    A hidden friend is a syntactic member-declaration, but is it a "member
    declaration"?  CWG was ambivalent, and referred the question to EWG as a
    design choice.  But recently Patrick mentioned that the current G++ choice
    not to treat it as a "member declaration" was making his library work
    significantly more cumbersome, so let's go ahead and vote the other way.
    
    This means that the testcases for 100502 and 58993 are now accepted.
    
            DR1699
            PR c++/100502
            PR c++/58993
    
    gcc/cp/ChangeLog:
    
            * friend.cc (is_friend): Hidden friends count as members.
            * search.cc (friend_accessible_p): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/access37.C: Now OK.
            * g++.dg/template/friend69.C: Now OK.
            * g++.dg/lookup/friend23.C: New test.

Diff:
---
 gcc/cp/friend.cc                         |  2 ++
 gcc/cp/search.cc                         |  7 ++-----
 gcc/testsuite/g++.dg/lookup/friend23.C   | 17 +++++++++++++++++
 gcc/testsuite/g++.dg/template/access37.C |  8 ++++----
 gcc/testsuite/g++.dg/template/friend69.C |  4 ++--
 5 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/gcc/cp/friend.cc b/gcc/cp/friend.cc
index 124ed4f3962..bf37dadeb62 100644
--- a/gcc/cp/friend.cc
+++ b/gcc/cp/friend.cc
@@ -131,6 +131,8 @@ is_friend (tree type, tree supplicant)
     {
       if (DECL_FUNCTION_MEMBER_P (supplicant))
 	context = DECL_CONTEXT (supplicant);
+      else if (tree fc = DECL_FRIEND_CONTEXT (supplicant))
+	context = fc;
       else
 	context = NULL_TREE;
     }
diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc
index b86b3a24080..10863a40b11 100644
--- a/gcc/cp/search.cc
+++ b/gcc/cp/search.cc
@@ -734,12 +734,9 @@ friend_accessible_p (tree scope, tree decl, tree type, tree otype)
 	  && friend_accessible_p (DECL_CONTEXT (scope), decl, type, otype))
 	return 1;
       /* Perhaps SCOPE is a friend function defined inside a class from which
-	 DECL is accessible.  Checking this is necessary only when the class
-	 is dependent, for otherwise add_friend will already have added the
-	 class to SCOPE's DECL_BEFRIENDING_CLASSES.  */
+	 DECL is accessible.  */
       if (tree fctx = DECL_FRIEND_CONTEXT (scope))
-	if (dependent_type_p (fctx)
-	    && protected_accessible_p (decl, fctx, type, otype))
+	if (friend_accessible_p (fctx, decl, type, otype))
 	  return 1;
     }
 
diff --git a/gcc/testsuite/g++.dg/lookup/friend23.C b/gcc/testsuite/g++.dg/lookup/friend23.C
new file mode 100644
index 00000000000..f7b26c9e3ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/friend23.C
@@ -0,0 +1,17 @@
+template <class Derived>
+struct base {
+  friend void bar(Derived& d) {
+    d.bar(); // access in inline friend of friend, ok?
+  }
+};
+
+class derived : base<derived> {
+  friend class base<derived>;
+  void bar() {}
+};
+
+int main() {
+  derived d;
+  bar(d);
+}
+
diff --git a/gcc/testsuite/g++.dg/template/access37.C b/gcc/testsuite/g++.dg/template/access37.C
index 5be532c75b0..407a7dc0f2d 100644
--- a/gcc/testsuite/g++.dg/template/access37.C
+++ b/gcc/testsuite/g++.dg/template/access37.C
@@ -6,10 +6,10 @@ struct EnumeratorRange {
     EnumeratorRange range_;
 
     friend void f(Iterator i) {
-      i.range_.end_reached_; // { dg-error "private" }
-      i.range_.EnumeratorRange::end_reached_; // { dg-error "private" }
-      &i.range_.end_reached_; // { dg-error "private" }
-      &i.range_.EnumeratorRange::end_reached_; // { dg-error "private" }
+      i.range_.end_reached_;
+      i.range_.EnumeratorRange::end_reached_;
+      &i.range_.end_reached_;
+      &i.range_.EnumeratorRange::end_reached_;
     }
   };
 
diff --git a/gcc/testsuite/g++.dg/template/friend69.C b/gcc/testsuite/g++.dg/template/friend69.C
index f3086a9f980..9bec6ba5846 100644
--- a/gcc/testsuite/g++.dg/template/friend69.C
+++ b/gcc/testsuite/g++.dg/template/friend69.C
@@ -12,7 +12,7 @@ protected:
 
 struct A {
   friend void g(A) {
-    B::f(); // { dg-error "private" }
-    B::g(); // { dg-error "protected" }
+    B::f();
+    B::g();
   }
 };


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-15 16:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-15 16:45 [gcc r13-465] c++: hidden friend access [DR1699] Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).