diff gcc/cp/friend.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/cp/friend.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/cp/friend.c	Thu Oct 25 07:37:49 2018 +0900
@@ -1,5 +1,5 @@
 /* Help friends in C++.
-   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   Copyright (C) 1997-2018 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -173,6 +173,12 @@
   if (decl == error_mark_node)
     return;
 
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      && DECL_TEMPLATE_INSTANTIATION (decl))
+    /* We'll have parsed this as a declaration, and therefore not
+       marked the lookup set for keeping.  Do that now.  */
+    lookup_keep (DECL_TI_TEMPLATE (decl));
+
   typedecl = TYPE_MAIN_DECL (type);
   list = DECL_FRIENDLIST (typedecl);
   name = DECL_NAME (decl);
@@ -283,24 +289,22 @@
     return;
 
   if (friend_depth)
-    /* 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.  */
     {
+      /* [temp.friend] Friend declarations shall not declare partial
+	 specializations.  */
       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 %qT declared %<friend%>",
 		 friend_type);
 	  return;
 	}
+
       if (TYPE_TEMPLATE_INFO (friend_type)
 	  && !PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (friend_type)))
 	{
+	  auto_diagnostic_group d;
 	  error ("%qT is not a template", friend_type);
 	  inform (location_of (friend_type), "previous declaration here");
 	  if (TYPE_CLASS_SCOPE_P (friend_type)
@@ -311,7 +315,11 @@
 	  return;
 	}
     }
-  else if (same_type_p (type, friend_type))
+
+  /* It makes sense for a template class to be friends with itself,
+     that means the instantiations can be friendly.  Other cases are
+     not so meaningful.  */
+  if (!friend_depth && same_type_p (type, friend_type))
     {
       if (complain)
 	warning (0, "class %qT is implicitly friends with itself",
@@ -377,6 +385,7 @@
 		}
 	      if (template_member_p && !DECL_CLASS_TEMPLATE_P (decl))
 		{
+		  auto_diagnostic_group d;
 		  error ("%qT is not a member class template of %qT",
 			 name, ctype);
 		  inform (DECL_SOURCE_LOCATION (decl),
@@ -386,6 +395,7 @@
 	      if (!template_member_p && (TREE_CODE (decl) != TYPE_DECL
 					 || !CLASS_TYPE_P (TREE_TYPE (decl))))
 		{
+		  auto_diagnostic_group d;
 		  error ("%qT is not a nested class of %qT",
 			 name, ctype);
 		  inform (DECL_SOURCE_LOCATION (decl),
@@ -494,7 +504,8 @@
   if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
     {
       declarator = TREE_OPERAND (declarator, 0);
-      declarator = OVL_NAME (declarator);
+      if (!identifier_p (declarator))
+	declarator = OVL_NAME (declarator);
     }
 
   if (ctype)
@@ -628,6 +639,7 @@
 	      static int explained;
 	      bool warned;
 
+	      auto_diagnostic_group d;
 	      warned = warning (OPT_Wnon_template_friend, "friend declaration "
 				"%q#D declares a non-template function", decl);
 	      if (! explained && warned)