diff mbox

C++ PATCH for N3922 (direct-initialization from { x })

Message ID 548B29A7.9050105@redhat.com
State New
Headers show

Commit Message

Jason Merrill Dec. 12, 2014, 5:45 p.m. UTC
N3922 changed Unicorn initialization such that while 
copy-list-initialization of an auto variable still deduces 
std::initializer_list<T>, direct-list-initialization from a list with a 
single element deduces the type of the element and from a list with 
multiple elements is ill-formed.

I've made the ill-formed case a permerror to help with transition for 
affected code (if there is any).

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

Patch

commit bd12f74cb9c8258307883bf07daeeae5305cad34
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Jun 20 14:22:26 2014 +0200

    	N3922
    	* pt.c (do_auto_deduction): In direct-init context, { x } deduces
    	from x.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index efc2001..5ed9b2c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5546,6 +5546,8 @@  reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
 	 of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is
 	 a CONSTRUCTOR (with a record type).  */
       if (TREE_CODE (init) == CONSTRUCTOR
+	  /* Don't complain about a capture-init.  */
+	  && !CONSTRUCTOR_IS_DIRECT_INIT (init)
 	  && BRACE_ENCLOSED_INITIALIZER_P (init))  /* p7626.C */
 	{
 	  if (SCALAR_TYPE_P (type))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d8a9c5b..8a663d9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -22117,7 +22117,21 @@  do_auto_deduction (tree type, tree init, tree auto_node)
      initializer is a braced-init-list (8.5.4), with
      std::initializer_list<U>.  */
   if (BRACE_ENCLOSED_INITIALIZER_P (init))
-    type = listify_autos (type, auto_node);
+    {
+      if (!DIRECT_LIST_INIT_P (init))
+	type = listify_autos (type, auto_node);
+      else if (CONSTRUCTOR_NELTS (init) == 1)
+	init = CONSTRUCTOR_ELT (init, 0)->value;
+      else
+	{
+	  if (permerror (input_location, "direct-list-initialization of "
+			 "%<auto%> requires exactly one element"))
+	    inform (input_location,
+		    "for deduction to %<std::initializer_list%>, use copy-"
+		    "list-initialization (i.e. add %<=%> before the %<{%>)");
+	  type = listify_autos (type, auto_node);
+	}
+    }
 
   init = resolve_nondeduced_context (init);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-n3922.C b/gcc/testsuite/g++.dg/cpp0x/initlist-n3922.C
new file mode 100644
index 0000000..4dadfc9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-n3922.C
@@ -0,0 +1,15 @@ 
+// N3922
+// { dg-do compile { target c++11 } }
+
+#include <initializer_list>
+template <class T, class U> struct same_type;
+template <class T> struct same_type<T,T> {};
+
+auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
+same_type<decltype(x1),std::initializer_list<int>> s1;
+auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
+same_type<decltype(x4),std::initializer_list<int>> s4;
+auto x5{ 3 }; // decltype(x5) is int
+same_type<decltype(x5),int> s5;
+auto x2 = { 1, 2.0 }; // { dg-error "initializer_list" } cannot deduce element type
+auto x3{ 1, 2 }; // { dg-error "one element" } not a single element
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init5.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init5.C
index 5976de0..1b287a1 100644
--- a/gcc/testsuite/g++.dg/cpp1y/lambda-init5.C
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init5.C
@@ -6,5 +6,5 @@ 
 int main()
 {
   if ([x(42)]{ return x; }() != 42) __builtin_abort();
-  if ([x{1,2}]{ return x.begin()[0]; }() != 1) __builtin_abort();
+  if ([x{24}]{ return x; }() != 24) __builtin_abort();
 }