The passage quoted talks about an initializer list containing a single expression, but a braced-init-list is not an expression.
Tested x86_64-pc-linux-gnu, applying to trunk. * pt.c (do_class_deduction): Don't try the single element deduction if the single element is also a braced list. --- gcc/cp/pt.c | 21 ++++++++++-------- .../g++.dg/cpp1z/class-deduction65.C | 22 +++++++++++++++++++ gcc/cp/ChangeLog | 4 ++++ 3 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction65.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3a11eaa7630..515f9d585cf 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -27327,15 +27327,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 <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{{}}; +} diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e7521446b59..acbb74b6af3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-04-19 Jason Merrill <ja...@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. base-commit: dbb68bd891ba4d345f3667c3ae7f1bfda04233b2 prerequisite-patch-id: 7a1f94e26f7a69284c97add19c28b3b39b2cb58f -- 2.20.1