From 1474a2e567653b9a1856b4cb28a64a8eeb3c7c9d Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 20 Apr 2019 02:18:39 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/pt.c | 21 ++++++++++-------- .../g++.dg/cpp1z/class-deduction65.C | 22 +++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction65.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9e2c46624de..11fc9de29b0 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 6d4140fb018..5f73fac3e8f 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 00000000000..e9711c1acb8 --- /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{{}}; +} -- 2.30.2