P0702R1 - List deduction of vector.
authorJason Merrill <jason@redhat.com>
Wed, 26 Jul 2017 17:39:31 +0000 (13:39 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 26 Jul 2017 17:39:31 +0000 (13:39 -0400)
* pt.c (do_class_deduction): Special-case deduction from a single
element of related type.

From-SVN: r250584

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1z/class-deduction42.C [new file with mode: 0644]

index b2df1eff89662187f430964871bb0af9f697a0db..9e763ae6d627778df85f5f0204ced591d1227a5c 100644 (file)
@@ -1,3 +1,9 @@
+2017-07-26  Jason Merrill  <jason@redhat.com>
+
+       P0702R1 - List deduction of vector.
+       * pt.c (do_class_deduction): Special-case deduction from a single
+       element of related type.
+
 2017-07-26  Leonid Koppel  <lkoppel@uwaterloo.ca>
 
         PR c++/67054 - Inherited ctor with non-default-constructible members
index bb323534ec05e9691a46f74feb1a039b5740b1e6..173ec3f303bac9d1529f652dfaf5319e8a375d8f 100644 (file)
@@ -25331,6 +25331,24 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
   else if (BRACE_ENCLOSED_INITIALIZER_P (init))
     {
       try_list_ctor = TYPE_HAS_LIST_CTOR (type);
+      if (try_list_ctor && CONSTRUCTOR_NELTS (init) == 1)
+       {
+         /* As an exception, the first phase in 16.3.1.7 (considering the
+            initializer list as a single argument) is omitted if the
+            initializer list consists of a single expression of type cv U,
+            where U is a specialization of C or a class derived from a
+            specialization of C.  */
+         tree elt = CONSTRUCTOR_ELT (init, 0)->value;
+         tree etype = TREE_TYPE (elt);
+
+         tree tparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
+         tree targs = make_tree_vec (TREE_VEC_LENGTH (tparms));
+         int err = unify (tparms, targs, type, etype,
+                          UNIFY_ALLOW_DERIVED, /*explain*/false);
+         if (err == 0)
+           try_list_ctor = false;
+         ggc_free (targs);
+       }
       if (try_list_ctor || is_std_init_list (type))
        args = make_tree_vector_single (init);
       else
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction42.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction42.C
new file mode 100644 (file)
index 0000000..8217fd4
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-options -std=c++1z }
+
+#include <initializer_list>
+
+template <class,class> struct same;
+template <class T> struct same<T,T> { };
+
+template <class T>
+struct A
+{
+  A(const A&);
+  A(std::initializer_list<T>);
+};
+
+A a { 1 };
+A b { a };
+
+same<decltype (a), decltype (b)> s;
+