From 6fb7e3c29188ab7cde0b963957caf6182536c77d Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 16 Oct 2020 11:00:12 -0400 Subject: [PATCH] c++: Deducing type from initializer_list [PR93107] In this testcase we weren't able to deduce b's type: template void Task() { } auto b = { &Task }; because resolve_nondeduced_context doesn't iterate on the {}'s elements. So make sure to look into {} too. We don't need to handle nested {} here. We could either tweak resolve_nondeduced_context to handle CONSTRUCTORs or add a _ctor version, but then resolve_nondeduced_context_or_error would need some changes too -- it'd have to check the result of a call to r_n_c for each element. gcc/cp/ChangeLog: PR c++/93107 * pt.c (do_auto_deduction): Call resolve_nondeduced_context for the elements of a { } list. gcc/testsuite/ChangeLog: PR c++/93107 * g++.dg/cpp0x/initlist-deduce3.C: New test. --- gcc/cp/pt.c | 8 ++++++- gcc/testsuite/g++.dg/cpp0x/initlist-deduce3.C | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-deduce3.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 531554d702d..b569644514c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -29241,7 +29241,13 @@ do_auto_deduction (tree type, tree init, tree auto_node, if (type == error_mark_node) return error_mark_node; - init = resolve_nondeduced_context (init, complain); + if (BRACE_ENCLOSED_INITIALIZER_P (init)) + /* We don't recurse here because we can't deduce from a nested + initializer_list. */ + for (constructor_elt &elt : *CONSTRUCTOR_ELTS (init)) + elt.value = resolve_nondeduced_context (elt.value, complain); + else + init = resolve_nondeduced_context (init, complain); if (context == adc_decomp_type && auto_node == type diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-deduce3.C b/gcc/testsuite/g++.dg/cpp0x/initlist-deduce3.C new file mode 100644 index 00000000000..b8417d7bf0c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-deduce3.C @@ -0,0 +1,22 @@ +// PR c++/93107 +// { dg-do compile { target c++11 } } + +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() {} + +auto a = &Task; +auto b = { &Task }; +auto e{ &Task }; +auto f = { &Task, &Task }; +std::initializer_list c = { &Task }; +auto d = { static_cast(&Task) }; -- 2.30.2