In this testcase we weren't able to deduce b's type: template<typename T> void Task() { } auto b = { &Task<int> };
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. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? 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 | 6 ++++- gcc/testsuite/g++.dg/cpp0x/initlist-deduce3.C | 22 +++++++++++++++++++ 2 files changed, 27 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 2a9a8fafaca..b7e8a47bde8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -29240,7 +29240,11 @@ 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)) + 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<typename T> struct initializer_list { + const T *ptr; + size_t n; + initializer_list(const T*, size_t); + }; +} + +template<typename T> +void Task() {} + +auto a = &Task<int>; +auto b = { &Task<int> }; +auto e{ &Task<int> }; +auto f = { &Task<int>, &Task<int> }; +std::initializer_list<void(*)()> c = { &Task<int> }; +auto d = { static_cast<void(*)()>(&Task<int>) }; base-commit: 1e8e49f135c814bd268289609dd0aea305ed546e -- 2.26.2