From 44ea0c47103850873c00f4f60a74e18fd25dc640 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 4 Jan 2017 02:59:16 +0000 Subject: [PATCH] Fix deduction of pack elements after a braced-init-list. Previously, if the arguments for a parameter pack contained a braced-init-list, we would abort deduction (keeping the pack deductions from prior arguments) at the point when we reached the braced-init-list, resulting in wrong deductions and rejects-valids. We now just leave a "hole" in the pack for such an argument, which needs to be filled by another deduction of the same pack. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290933 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateDeduction.cpp | 8 ++------ .../cxx0x-initializer-stdinitializerlist.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 7923e7d7e6..6dae37be27 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3468,12 +3468,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( if (InitListExpr *ILE = dyn_cast(Arg)) { TemplateDeductionResult Result; if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, - Info, Deduced, TDF, Result)) { - // FIXME: Bailing out here is wrong; we could still need to deduce - // from later pack elements. - ++ArgIdx; - break; - } + Info, Deduced, TDF, Result)) + continue; if (Result) return Result; diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index 060a0f236b..c8595d2e36 100644 --- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -103,6 +103,12 @@ T deduce(std::initializer_list); // expected-note {{conflicting types for par template T deduce_ref(const std::initializer_list&); // expected-note {{conflicting types for parameter 'T' ('int' vs. 'double')}} +template struct pair { pair(...); }; +template void deduce_pairs(std::initializer_list>); +struct WithIntType { typedef int type; }; + +template void deduce_after_init_list_in_pack(void (*)(T...), T...); // expected-note {{ vs. <(no value), double>}} + void argument_deduction() { static_assert(same_type::value, "bad deduction"); static_assert(same_type::value, "bad deduction"); @@ -113,6 +119,14 @@ void argument_deduction() { static_assert(same_type::value, "bad deduction"); deduce_ref({1, 2.0}); // expected-error {{no matching function}} + + pair pi; + pair pf; + deduce_pairs({pi, pi, pi}); // ok + deduce_pairs({pi, pf, pi}); // FIXME: This should be rejected, as we fail to produce a type that exactly matches the argument type. + + deduce_after_init_list_in_pack((void(*)(int,int))0, {}, 0); + deduce_after_init_list_in_pack((void(*)(int,int))0, {}, 0.0); // expected-error {{no matching function}} } void auto_deduction() { -- 2.40.0