This patch fixes pr82710, were we erroneously warn on something like:
   friend class_X (::other::name (...));
the parens are needed, otherwise the '::other' is taken to be a qualified lookup inside the class_X.

Unfortunately, at the point we can check, we've lost information that '::' was used. So I back off when we see a qualified name there.

nathan
--
Nathan Sidwell
2017-11-02  Nathan Sidwell  <nat...@acm.org>

	PR c++/82710
	* decl.c (grokdeclarator): Don't warn when parens protect a return
	type from a qualified name.

	PR c++/82710
	* g++.dg/warn/pr82710.C: New.

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 254344)
+++ cp/decl.c	(working copy)
@@ -10788,18 +10788,25 @@ grokdeclarator (const cp_declarator *dec
 					    attr_flags);
 	}
 
+      inner_declarator = declarator->declarator;
+
       /* We don't want to warn in parmeter context because we don't
 	 yet know if the parse will succeed, and this might turn out
 	 to be a constructor call.  */
       if (decl_context != PARM
-	  && declarator->parenthesized != UNKNOWN_LOCATION)
+	  && declarator->parenthesized != UNKNOWN_LOCATION
+	  /* If the type is a class and the inner name used a global
+	     namespace qualifier, we need the parens.  Unfortunately
+	     all we can tell is that a qualified name was used.  */
+	  && !(CLASS_TYPE_P (type)
+	       && inner_declarator
+	       && inner_declarator->kind == cdk_id
+	       && inner_declarator->u.id.qualifying_scope))
 	warning_at (declarator->parenthesized, OPT_Wparentheses,
 		    "unnecessary parentheses in declaration of %qs", name);
       if (declarator->kind == cdk_id || declarator->kind == cdk_decomp)
 	break;
 
-      inner_declarator = declarator->declarator;
-
       switch (declarator->kind)
 	{
 	case cdk_array:
Index: testsuite/g++.dg/warn/pr82710.C
===================================================================
--- testsuite/g++.dg/warn/pr82710.C	(revision 0)
+++ testsuite/g++.dg/warn/pr82710.C	(working copy)
@@ -0,0 +1,32 @@
+// { dg-additional-options -Wparentheses }
+
+// the MVP warning triggered on a friend decl.  */
+class X;
+
+namespace here 
+{
+  // these friends
+  X friendFunc1();
+  X *friendFunc2 ();
+  int friendFunc3 ();
+}
+
+namespace nm
+{
+  namespace here 
+  {
+    // Not these friends
+    void friendFunc1 ();
+    void friendFunc2 ();
+    void friendFunc3 ();
+  }
+
+  class TestClass
+  {
+    friend X (::here::friendFunc1 ()); // parens are needed
+    friend X *(::here::friendFunc2 ()); // { dg-warning "" }
+    friend X *::here::friendFunc2 ();
+    friend int (::here::friendFunc3 ()); // { dg-warning "" }
+  };
+}
+

Reply via email to