diff mbox

[C++] PR 60686

Message ID 53BD1469.7070401@oracle.com
State New
Headers show

Commit Message

Paolo Carlini July 9, 2014, 10:07 a.m. UTC
Hi,

On 07/09/2014 12:39 AM, Jason Merrill wrote:
> On 07/07/2014 11:15 AM, Paolo Carlini wrote:
>> +      error ("only declarations can be marked %<explicit%>");
>
> That's pretty unclear, since a definition is a declaration.
>
> Let's split this into three error messages: If the problem is that 
> we're outside the class, we should say that.  If the problem is that 
> it's not a constructor or conversion function, we should say that.  If 
> the problem is that it's not a member of the current class, we should 
> say that.
Ok. In terms of wording, for the first case we can consistently follow 
the example of 'virtual'. For the second case, we can simply extend the 
existing wording. 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... I tested the below.

Thanks,
Paolo.

///////////////////
/cp
2014-07-09  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/60686
	* decl.c (grokdeclarator): Adjust error message about 'explicit'
	outside class declaration for C++11.

/testsuite
2014-07-09  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/60686
	* g++.dg/cpp0x/explicit8.C: New.

Comments

Jason Merrill July 9, 2014, 8:34 p.m. UTC | #1
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);
};

Jason
diff mbox

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 212385)
+++ cp/decl.c	(working copy)
@@ -10117,9 +10117,14 @@  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
+	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,14 @@ 
+// 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" }