diff options
author | Jason Merrill <jason@redhat.com> | 2006-07-05 15:44:28 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2006-07-05 15:44:28 -0400 |
commit | 03b1c2062ba9877841bc9b8553cf069bed7e33bf (patch) | |
tree | 05e265b45537a3c04e8ec138ba9dd7850fe1ccb7 | |
parent | ad6d4e435e96bddcf72757a4e5df802e6c447922 (diff) | |
download | gcc-03b1c2062ba9877841bc9b8553cf069bed7e33bf.zip gcc-03b1c2062ba9877841bc9b8553cf069bed7e33bf.tar.gz gcc-03b1c2062ba9877841bc9b8553cf069bed7e33bf.tar.bz2 |
re PR c++/18681 ([DR 45] template friend declaration not recognized)
PR c++/18681
* friend.c (is_friend): Fix DR 45 implementation.
From-SVN: r115208
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/friend.c | 31 | ||||
-rw-r--r-- | gcc/cp/search.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/friend10.C | 22 |
4 files changed, 47 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d2c0562..b1a1cbd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2006-07-05 Jason Merrill <jason@redhat.com> + + PR c++/18681 + * friend.c (is_friend): Fix DR 45 implementation. + 2006-07-05 Richard Guenther <rguenther@suse.de> Andrew Pinski <pinskia@gcc.gnu.org> diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index ac73e5f..0c9712e 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -78,13 +78,8 @@ is_friend (tree type, tree supplicant) else /* It's a type. */ { - /* Nested classes are implicitly friends of their enclosing types, as - per core issue 45 (this is a change from the standard). */ - for (context = supplicant; - context && TYPE_P (context); - context = TYPE_CONTEXT (context)) - if (type == context) - return 1; + if (same_type_p (supplicant, type)) + return 1; list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type))); for (; list ; list = TREE_CHAIN (list)) @@ -98,13 +93,23 @@ is_friend (tree type, tree supplicant) } } - if (declp && DECL_FUNCTION_MEMBER_P (supplicant)) - context = DECL_CONTEXT (supplicant); - else if (! declp) - /* Local classes have the same access as the enclosing function. */ - context = decl_function_context (TYPE_MAIN_DECL (supplicant)); + if (declp) + { + if (DECL_FUNCTION_MEMBER_P (supplicant)) + context = DECL_CONTEXT (supplicant); + else + context = NULL_TREE; + } else - context = NULL_TREE; + { + if (TYPE_CLASS_SCOPE_P (supplicant)) + /* Nested classes get the same access as their enclosing types, as + per DR 45 (this is a change from the standard). */ + context = TYPE_CONTEXT (supplicant); + else + /* Local classes have the same access as the enclosing function. */ + context = decl_function_context (TYPE_MAIN_DECL (supplicant)); + } /* A namespace is not friend to anybody. */ if (context && TREE_CODE (context) == NAMESPACE_DECL) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 21d1b77..0682ff2 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -792,8 +792,8 @@ friend_accessible_p (tree scope, tree decl, tree binfo) if (protected_accessible_p (decl, TREE_VALUE (t), binfo)) return 1; - /* Nested classes are implicitly friends of their enclosing types, as - per core issue 45 (this is a change from the standard). */ + /* Nested classes have the same access as their enclosing types, as + per DR 45 (this is a change from the standard). */ if (TYPE_P (scope)) for (t = TYPE_CONTEXT (scope); t && TYPE_P (t); t = TYPE_CONTEXT (t)) if (protected_accessible_p (decl, t, binfo)) diff --git a/gcc/testsuite/g++.dg/lookup/friend10.C b/gcc/testsuite/g++.dg/lookup/friend10.C new file mode 100644 index 0000000..fa2eccb --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/friend10.C @@ -0,0 +1,22 @@ +// PR c++/18681 +// Bug: The friend declaration in A failed to give C::D access to A::B +// as specified in DR 45. + +class A +{ + struct B; + friend class C; +}; + +class C +{ + struct D + { + void f(); + }; +}; + +void C::D::f() +{ + A::B* p; +} |