This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/71227 (error specializing friend)


My fix for 70522 caused us to reject this testcase as well. I think that this is correct; I don't see any reason why lookup to find a template to specialize should be treated differently from other normal lookup. But we could be more helpful in the diagnostic, especially since this breaks previously working code.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit fa370e284e8b04f85fb626b20919f52ef542748f
Author: Jason Merrill <jason@redhat.com>
Date:   Wed May 25 16:10:24 2016 -0400

    	PR c++/71227
    
    	* pt.c (check_explicit_specialization): Give better diagnostic about
    	specializing a hidden friend.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index df3d634..a57da62 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2807,12 +2807,22 @@ check_explicit_specialization (tree declarator,
 	      /* Find the namespace binding, using the declaration
 		 context.  */
 	      fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname,
-					   false, true);
+					   /*type*/false, /*complain*/true,
+					   /*hidden*/true);
 	      if (fns == error_mark_node || !is_overloaded_fn (fns))
 		{
 		  error ("%qD is not a template function", dname);
 		  fns = error_mark_node;
 		}
+	      else if (remove_hidden_names (fns) == NULL_TREE)
+		{
+		  tree fn = get_first_fn (fns);
+		  if (pedwarn (DECL_SOURCE_LOCATION (decl), 0,
+			       "friend declaration %qD is not visible to "
+			       "explicit specialization", fn))
+		    inform (DECL_SOURCE_LOCATION (fn),
+			    "friend declaration here");
+		}
 	    }
 
 	  declarator = lookup_template_function (fns, NULL_TREE);
diff --git a/gcc/testsuite/g++.dg/template/friend62.C b/gcc/testsuite/g++.dg/template/friend62.C
new file mode 100644
index 0000000..c9796c4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend62.C
@@ -0,0 +1,16 @@
+// PR c++/71227
+// { dg-options "" }
+
+class A {
+  public:
+    template<typename T>
+      friend int f(int x, T v) { // { dg-message "declaration" }
+        return x + v;
+      }
+};
+
+
+template<>
+int f(int x, int v) {		// { dg-warning "friend" }
+  return x + v;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]