]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/90190 - CTAD with list-constructor.
authorJason Merrill <jason@redhat.com>
Sat, 20 Apr 2019 06:18:39 +0000 (02:18 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 20 Apr 2019 06:18:39 +0000 (02:18 -0400)
The passage quoted talks about an initializer list containing a single
expression, but a braced-init-list is not an expression.

* pt.c (do_class_deduction): Don't try the single element deduction
if the single element is also a braced list.

From-SVN: r270468

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

index 9e2c46624de4067a4f6daacebd20a68e591687fb..11fc9de29b05c311da08d5354bd11acf381b82fb 100644 (file)
@@ -1,5 +1,9 @@
 2019-04-19  Jason Merrill  <jason@redhat.com>
 
+       PR c++/90190 - CTAD with list-constructor.
+       * pt.c (do_class_deduction): Don't try the single element deduction
+       if the single element is also a braced list.
+
        PR c++/90171 - ICE with destroying delete with size_t parm.
        * call.c (sized_deallocation_fn_p): New.  Use it instead of
        second_parm_is_size_t in most cases.
index 6d4140fb018eacb998a75de54ea69c95f566ae50..5f73fac3e8fb4bfac9c46c9e5f75fd0f8e11138c 100644 (file)
@@ -27325,15 +27325,18 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
             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 (!BRACE_ENCLOSED_INITIALIZER_P (elt))
+           {
+             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);
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction65.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction65.C
new file mode 100644 (file)
index 0000000..e9711c1
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/90190
+// { dg-do compile { target c++17 } }
+
+#include <initializer_list>
+
+enum class X {};
+
+struct Term {
+  double a;
+  X i;
+};
+
+template <class It = const Term *>
+struct sum {
+  sum(std::initializer_list<Term>) {}
+};
+
+int main() {
+  auto c2 = sum{{1, X()}, {2, X()}};
+  auto c1 = sum{{1, X()}};  // fails only this
+  auto c0 = sum{{}};
+}