diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d400b9f3eb2523962ec62ac0473a7c5522e62c7c..696df2bdd9f78d206f26e6c6a41fa3b780968ca3 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -30784,7 +30784,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, int flags /* = LOOKUP_NORMAL */, tree tmpl /* = NULL_TREE */) { - if (init == error_mark_node) + if (type == error_mark_node || init == error_mark_node) return error_mark_node; if (init && type_dependent_expression_p (init) @@ -30801,6 +30801,17 @@ do_auto_deduction (tree type, tree init, tree auto_node, auto_node. */ complain &= ~tf_partial; + if (init && BRACE_ENCLOSED_INITIALIZER_P (init)) + { + /* We don't recurse here because we can't deduce from a nested + initializer_list. */ + if (CONSTRUCTOR_ELTS (init)) + for (constructor_elt &elt : CONSTRUCTOR_ELTS (init)) + elt.value = resolve_nondeduced_context (elt.value, complain); + } + else if (init) + init = resolve_nondeduced_context (init, complain); + /* In C++23, we must deduce the type to int&& for code like decltype(auto) f(int&& x) { return (x); } or @@ -30852,24 +30863,12 @@ do_auto_deduction (tree type, tree init, tree auto_node, } } - if (type == error_mark_node) + if (type == error_mark_node || init == error_mark_node) return error_mark_node; - if (BRACE_ENCLOSED_INITIALIZER_P (init)) - { - /* We don't recurse here because we can't deduce from a nested - initializer_list. */ - if (CONSTRUCTOR_ELTS (init)) - for (constructor_elt &elt : CONSTRUCTOR_ELTS (init)) - elt.value = resolve_nondeduced_context (elt.value, complain); - } - else - init = resolve_nondeduced_context (init, complain); - tree targs; if (context == adc_decomp_type && auto_node == type - && init != error_mark_node && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) { /* [dcl.struct.bind]/1 - if decomposition declaration has no ref-qualifiers diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction114.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction114.C new file mode 100644 index 0000000000000000000000000000000000000000..daf30f8d158ef59fc41caff9fd4822224fd70903 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction114.C @@ -0,0 +1,28 @@ +// PR c++/106214 +// { dg-do compile { target c++17 } } +// A version of cpp0x/initlist-deduce3.C using list CTAD instead +// of ordinary auto deduction from an initializer list. + +using size_t = decltype(sizeof 0); + +namespace std { + template<typename T> struct initializer_list { + const T *ptr; + size_t n; + initializer_list(const T*, size_t); + }; +} + +template<typename T> +void Task() {} + +template<class T> +struct vector { + vector(std::initializer_list<T>); +}; + +vector a = &Task<int>; // { dg-error "deduction|no match" } +vector b = { &Task<int> }; +vector e{ &Task<int> }; +vector f = { &Task<int>, &Task<int> }; +vector d = { static_cast<void(*)()>(&Task<int>) };