diff options
Diffstat (limited to 'gcc/cp/friend.c')
-rw-r--r-- | gcc/cp/friend.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 7b718ace0df..0727c397cf4 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -64,6 +64,10 @@ is_friend (type, supplicant) if (supplicant == TREE_VALUE (friends)) return 1; + /* We haven't completed the instantiation yet. */ + if (TREE_CODE (supplicant) == TEMPLATE_DECL) + return 1; + /* Temporarily, we are more lenient to deal with nested friend functions, for which there can be more than one FUNCTION_DECL, despite being the @@ -203,24 +207,25 @@ make_friend_class (type, friend_type) return; } - if (CLASS_TYPE_P (friend_type) - && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type) - && uses_template_parms (friend_type)) - { - /* [temp.friend] - - Friend declarations shall not declare partial - specializations. */ - error ("partial specialization `%T' declared `friend'", - friend_type); - return; - } - if (processing_template_decl > template_class_depth (type)) /* If the TYPE is a template then it makes sense for it to be friends with itself; this means that each instantiation is friends with all other instantiations. */ - is_template_friend = 1; + { + if (CLASS_TYPE_P (friend_type) + && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type) + && uses_template_parms (friend_type)) + { + /* [temp.friend] + Friend declarations shall not declare partial + specializations. */ + error ("partial specialization `%T' declared `friend'", + friend_type); + return; + } + + is_template_friend = 1; + } else if (same_type_p (type, friend_type)) { pedwarn ("class `%T' is implicitly friends with itself", @@ -347,6 +352,8 @@ do_friend (ctype, declarator, decl, parmdecls, attrlist, if (is_friend_template) decl = DECL_TI_TEMPLATE (push_template_decl (decl)); + else if (DECL_TEMPLATE_INFO (decl)) + ; else if (template_class_depth (current_class_type)) decl = push_template_decl_real (decl, /*is_friend=*/1); |