Patchwork C++ PATCH for c++/54835 (value-list-initialization and explicit constructors)

login
register
mail settings
Submitter Jason Merrill
Date March 16, 2013, 7:33 p.m.
Message ID <5144C8F1.2060306@redhat.com>
Download mbox | patch
Permalink /patch/228245/
State New
Headers show

Comments

Jason Merrill - March 16, 2013, 7:33 p.m.
DR 1518 clarified that we need to check for the constructor being 
explicit even for value-initialization.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 5b4dec4223f320f314696b854481bbced847f1c9
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Feb 16 10:10:05 2013 -0500

    	DR 1518
    	PR c++/54835
    	* call.c (convert_like_real): Check for explicit constructors
    	even for value-initialization.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 530835b..e40c45f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5856,6 +5856,17 @@  convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 	tree convfn = cand->fn;
 	unsigned i;
 
+	/* When converting from an init list we consider explicit
+	   constructors, but actually trying to call one is an error.  */
+	if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
+	    /* Unless this is for direct-list-initialization.  */
+	    && !(BRACE_ENCLOSED_INITIALIZER_P (expr)
+		 && CONSTRUCTOR_IS_DIRECT_INIT (expr)))
+	  {
+	    error ("converting to %qT from initializer list would use "
+		   "explicit constructor %qD", totype, convfn);
+	  }
+
 	/* If we're initializing from {}, it's value-initialization.  */
 	if (BRACE_ENCLOSED_INITIALIZER_P (expr)
 	    && CONSTRUCTOR_NELTS (expr) == 0
@@ -5874,20 +5885,6 @@  convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 
 	expr = mark_rvalue_use (expr);
 
-	/* When converting from an init list we consider explicit
-	   constructors, but actually trying to call one is an error.  */
-	if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
-	    /* Unless this is for direct-list-initialization.  */
-	    && !(BRACE_ENCLOSED_INITIALIZER_P (expr)
-		 && CONSTRUCTOR_IS_DIRECT_INIT (expr))
-	    /* Unless we're calling it for value-initialization from an
-	       empty list, since that is handled separately in 8.5.4.  */
-	    && cand->num_convs > 0)
-	  {
-	    error ("converting to %qT from initializer list would use "
-		   "explicit constructor %qD", totype, convfn);
-	  }
-
 	/* Set user_conv_p on the argument conversions, so rvalue/base
 	   handling knows not to allow any more UDCs.  */
 	for (i = 0; i < cand->num_convs; ++i)
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist40.C b/gcc/testsuite/g++.dg/cpp0x/initlist40.C
index f270360..8cf36be 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist40.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist40.C
@@ -1,3 +1,4 @@ 
+// PR c++/54835, DR 1518
 // { dg-options "-std=c++0x" }
 
 struct A
@@ -7,6 +8,6 @@  struct A
 
 int main()
 {
-  A a1 = { };
+  A a1 = { };			// { dg-error "explicit" }
   A a2 = { 24 };		// { dg-error "explicit" }
 }