From: Patrick Palka Date: Mon, 8 May 2023 13:03:35 +0000 (-0400) Subject: c++: list CTAD and resolve_nondeduced_context [PR106214] X-Git-Tag: basepoints/gcc-15~9561 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06ef1583d68169d1a002f5e86189462bb748963c;p=thirdparty%2Fgcc.git c++: list CTAD and resolve_nondeduced_context [PR106214] This extends the PR93107 fix, which made us do resolve_nondeduced_context on the elements of an initializer list during auto deduction, to happen for CTAD as well. PR c++/106214 PR c++/93107 gcc/cp/ChangeLog: * pt.cc (do_auto_deduction): Move up resolve_nondeduced_context calls to happen before do_class_deduction. Add some error_mark_node tests. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/class-deduction114.C: New test. --- diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d400b9f3eb25..696df2bdd9f7 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 000000000000..daf30f8d158e --- /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 struct initializer_list { + const T *ptr; + size_t n; + initializer_list(const T*, size_t); + }; +} + +template +void Task() {} + +template +struct vector { + vector(std::initializer_list); +}; + +vector a = &Task; // { dg-error "deduction|no match" } +vector b = { &Task }; +vector e{ &Task }; +vector f = { &Task, &Task }; +vector d = { static_cast(&Task) };