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"
}
+};