From: Jason Merrill Date: Sat, 20 Apr 2019 06:18:39 +0000 (-0400) Subject: PR c++/90190 - CTAD with list-constructor. X-Git-Tag: basepoints/gcc-10~87 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1474a2e567653b9a1856b4cb28a64a8eeb3c7c9d;p=thirdparty%2Fgcc.git PR c++/90190 - CTAD with list-constructor. 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9e2c46624de4..11fc9de29b05 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-04-19 Jason Merrill + 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. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6d4140fb018e..5f73fac3e8fb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 index 000000000000..e9711c1acb8e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction65.C @@ -0,0 +1,22 @@ +// PR c++/90190 +// { dg-do compile { target c++17 } } + +#include + +enum class X {}; + +struct Term { + double a; + X i; +}; + +template +struct sum { + sum(std::initializer_list) {} +}; + +int main() { + auto c2 = sum{{1, X()}, {2, X()}}; + auto c1 = sum{{1, X()}}; // fails only this + auto c0 = sum{{}}; +}