diff options
author | Patrick Palka <ppalka@redhat.com> | 2023-05-08 09:03:35 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2023-05-08 09:03:35 -0400 |
commit | 06ef1583d68169d1a002f5e86189462bb748963c (patch) | |
tree | ca967ca1b369f71e927b3c3dd2dd780cc6703b36 | |
parent | e2b993db57f90fedd1bd7756f7ad4c5bfded4b8f (diff) | |
download | gcc-06ef1583d68169d1a002f5e86189462bb748963c.zip gcc-06ef1583d68169d1a002f5e86189462bb748963c.tar.gz gcc-06ef1583d68169d1a002f5e86189462bb748963c.tar.bz2 |
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.
-rw-r--r-- | gcc/cp/pt.cc | 27 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/class-deduction114.C | 28 |
2 files changed, 41 insertions, 14 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d400b9f..696df2b 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 0000000..daf30f8 --- /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>) }; |