pt.c (do_auto_deduction): In direct-init context, { x } deduces from x.
authorJason Merrill <jason@redhat.com>
Fri, 12 Dec 2014 17:52:28 +0000 (12:52 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 12 Dec 2014 17:52:28 +0000 (12:52 -0500)
N3922
* pt.c (do_auto_deduction): In direct-init context, { x } deduces
from x.

From-SVN: r218685

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/initlist-n3922.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/lambda-init5.C

index 828848164ed4b5d60695db293ba9327e88772116..4fb8a13c3224f7b83018eba08e918d7ca89adb9b 100644 (file)
@@ -1,5 +1,9 @@
 2014-12-12  Jason Merrill  <jason@redhat.com>
 
+       N3922
+       * pt.c (do_auto_deduction): In direct-init context, { x } deduces
+       from x.
+
        * cp-tree.h (NAMESPACE_ABI_TAG): New.
        * name-lookup.c (handle_namespace_attrs): Set it.
        * class.c (check_tag): Split out from find_abi_tags_r.
index efc20012831a3fb28b810c0e18b703ef8eae9281..5ed9b2c216a58933e50bde3cb2af3c185a889f46 100644 (file)
@@ -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))
index d8a9c5b1b32b32b9c9276aa33cbe68546b02c1e0..8a663d98c4727946e0c3354598584167f9f816aa 100644 (file)
@@ -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 (file)
index 0000000..4dadfc9
--- /dev/null
@@ -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
index 5976de0f0732ca18c72c01b35978695dd94e7cb2..1b287a16888c6d63eba8e6d25974ecabc1297f66 100644 (file)
@@ -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();
 }