Commit 03b1c206 by Jason Merrill Committed by Jason Merrill

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
parent ad6d4e43
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> 2006-07-05 Richard Guenther <rguenther@suse.de>
Andrew Pinski <pinskia@gcc.gnu.org> Andrew Pinski <pinskia@gcc.gnu.org>
......
...@@ -78,13 +78,8 @@ is_friend (tree type, tree supplicant) ...@@ -78,13 +78,8 @@ is_friend (tree type, tree supplicant)
else else
/* It's a type. */ /* It's a type. */
{ {
/* Nested classes are implicitly friends of their enclosing types, as if (same_type_p (supplicant, type))
per core issue 45 (this is a change from the standard). */ return 1;
for (context = supplicant;
context && TYPE_P (context);
context = TYPE_CONTEXT (context))
if (type == context)
return 1;
list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type))); list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
for (; list ; list = TREE_CHAIN (list)) for (; list ; list = TREE_CHAIN (list))
...@@ -98,13 +93,23 @@ is_friend (tree type, tree supplicant) ...@@ -98,13 +93,23 @@ is_friend (tree type, tree supplicant)
} }
} }
if (declp && DECL_FUNCTION_MEMBER_P (supplicant)) if (declp)
context = DECL_CONTEXT (supplicant); {
else if (! declp) if (DECL_FUNCTION_MEMBER_P (supplicant))
/* Local classes have the same access as the enclosing function. */ context = DECL_CONTEXT (supplicant);
context = decl_function_context (TYPE_MAIN_DECL (supplicant)); else
context = NULL_TREE;
}
else 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. */ /* A namespace is not friend to anybody. */
if (context && TREE_CODE (context) == NAMESPACE_DECL) if (context && TREE_CODE (context) == NAMESPACE_DECL)
......
...@@ -792,8 +792,8 @@ friend_accessible_p (tree scope, tree decl, tree binfo) ...@@ -792,8 +792,8 @@ friend_accessible_p (tree scope, tree decl, tree binfo)
if (protected_accessible_p (decl, TREE_VALUE (t), binfo)) if (protected_accessible_p (decl, TREE_VALUE (t), binfo))
return 1; return 1;
/* Nested classes are implicitly friends of their enclosing types, as /* Nested classes have the same access as their enclosing types, as
per core issue 45 (this is a change from the standard). */ per DR 45 (this is a change from the standard). */
if (TYPE_P (scope)) if (TYPE_P (scope))
for (t = TYPE_CONTEXT (scope); t && TYPE_P (t); t = TYPE_CONTEXT (t)) for (t = TYPE_CONTEXT (scope); t && TYPE_P (t); t = TYPE_CONTEXT (t))
if (protected_accessible_p (decl, t, binfo)) if (protected_accessible_p (decl, t, binfo))
......
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment