Hi,

On 07/09/2014 10:34 PM, Jason Merrill wrote:
On 07/09/2014 06:07 AM, Paolo Carlini wrote:
The third case, I don't think it can really happen,
because there are earlier checks which simply return error_mark_node if
a declaration is within the wrong class...
Not if it's a friend declaration:

struct A {
  explicit A(int);
};

struct B {
  explicit friend A::A(int);
};
Oops, sorry, we even test for friends... Then I'm finishing testing the below.

Thanks,
Paolo.

//////////////////////
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 212385)
+++ cp/decl.c   (working copy)
@@ -10117,9 +10117,16 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (explicitp == 1 || (explicitp && friendp))
     {
-      /* [dcl.fct.spec] The explicit specifier shall only be used in
-        declarations of constructors within a class definition.  */
-      error ("only declarations of constructors can be %<explicit%>");
+      /* [dcl.fct.spec] (C++11) The explicit specifier shall be used only
+        in the declaration of a constructor or conversion function within
+        a class definition.  */
+      if (!current_class_type)
+       error ("%<explicit%> outside class declaration");
+      else if (friendp)
+       error ("%<explicit%> in friend declaration");
+      else
+       error ("only declarations of constructors and conversion operators "
+              "can be %<explicit%>");
       explicitp = 0;
     }
 
Index: testsuite/g++.dg/cpp0x/explicit8.C
===================================================================
--- testsuite/g++.dg/cpp0x/explicit8.C  (revision 0)
+++ testsuite/g++.dg/cpp0x/explicit8.C  (working copy)
@@ -0,0 +1,22 @@
+// PR c++/60686
+// { dg-do compile { target c++11 } }
+
+struct A {
+  explicit operator int() const;
+};
+
+explicit inline A::operator int() const { return 1; }  // { dg-error 
"'explicit' outside class declaration" }
+
+struct B {
+  explicit void f();  // { dg-error "only declarations of constructors and 
conversion operators can be 'explicit'" }
+};
+
+explicit void B::f() { }  // { dg-error "'explicit' outside class declaration" 
}
+
+struct C {
+  explicit C(int);
+};
+
+struct D {
+  explicit friend C::C(int);  // { dg-error "'explicit' in friend declaration" 
}
+};

Reply via email to