PR c++/61490 - qualified-id in friend function definition.
authorMarek Polacek <polacek@redhat.com>
Fri, 21 Jun 2019 20:43:47 +0000 (20:43 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 21 Jun 2019 20:43:47 +0000 (20:43 +0000)
* decl.c (grokdeclarator): Diagnose qualified-id in friend function
definition.  Improve location for diagnostics of friend functions.

* g++.dg/diagnostic/friend2.C: New test.
* g++.dg/diagnostic/friend3.C: New test.

From-SVN: r272572

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/diagnostic/friend2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/diagnostic/friend3.C [new file with mode: 0644]

index 12da65e..9b75295 100644 (file)
@@ -1,5 +1,9 @@
 2019-06-21  Marek Polacek  <polacek@redhat.com>
 
+       PR c++/61490 - qualified-id in friend function definition.
+       * decl.c (grokdeclarator): Diagnose qualified-id in friend function
+       definition.  Improve location for diagnostics of friend functions.
+
        PR c++/60223 - ICE with T{} in non-deduced context.
        * pt.c (unify): Allow COMPOUND_LITERAL_P in a non-deduced context.
 
index 85f96f7..98b54d5 100644 (file)
@@ -11624,13 +11624,29 @@ grokdeclarator (const cp_declarator *declarator,
                    friendp = 0;
                  }
                if (decl_context == NORMAL)
-                 error ("friend declaration not in class definition");
+                 error_at (declarator->id_loc,
+                           "friend declaration not in class definition");
                if (current_function_decl && funcdef_flag)
                  {
-                   error ("cannot define friend function %qs in a local "
-                          "class definition", name);
+                   error_at (declarator->id_loc,
+                             "cannot define friend function %qs in a local "
+                             "class definition", name);
                    friendp = 0;
                  }
+               /* [class.friend]/6: A function can be defined in a friend
+                  declaration if the function name is unqualified.  */
+               if (funcdef_flag && in_namespace)
+                 {
+                   if (in_namespace == global_namespace)
+                     error_at (declarator->id_loc,
+                               "friend function definition %qs cannot have "
+                               "a name qualified with %<::%>", name);
+                   else
+                     error_at (declarator->id_loc,
+                               "friend function definition %qs cannot have "
+                               "a name qualified with %<%D::%>", name,
+                               in_namespace);
+                 }
              }
            else if (ctype && sfk == sfk_conversion)
              {
index e80c422..d5367b2 100644 (file)
@@ -1,5 +1,9 @@
 2019-06-21  Marek Polacek  <polacek@redhat.com>
 
+       PR c++/61490 - qualified-id in friend function definition.
+       * g++.dg/diagnostic/friend2.C: New test.
+       * g++.dg/diagnostic/friend3.C: New test.
+
        PR c++/60223 - ICE with T{} in non-deduced context.
        * g++.dg/cpp0x/nondeduced1.C: New test.
        * g++.dg/cpp0x/nondeduced2.C: New test.
diff --git a/gcc/testsuite/g++.dg/diagnostic/friend2.C b/gcc/testsuite/g++.dg/diagnostic/friend2.C
new file mode 100644 (file)
index 0000000..4f4ada8
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/61490
+// { dg-do compile }
+
+namespace N { void f (); }
+void f2 ();
+
+struct A {
+  friend void N::f () { } // { dg-error "15:friend function definition 'f' cannot have a name qualified with 'N::'" }
+  friend void ::f2 () { } // { dg-error "15:friend function definition 'f2' cannot have a name qualified with '::'" }
+};
diff --git a/gcc/testsuite/g++.dg/diagnostic/friend3.C b/gcc/testsuite/g++.dg/diagnostic/friend3.C
new file mode 100644 (file)
index 0000000..574d7ca
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile }
+
+void
+fn ()
+{
+  struct S {
+    friend void bar () { } // { dg-error "17:cannot define friend function 'bar' in a local class definition" }
+  };
+}