https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/79371
From 3e0c3db0d8500e5f2111e3603da3d8f2b1cd261d Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Wed, 24 Jan 2024 21:21:26 +0100 Subject: [PATCH 01/16] [Sema]Substitue template parameter packs when deduced from function parameter --- clang/lib/Sema/SemaTemplateDeduction.cpp | 63 +++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e9e7ab5bb6698a..46fa9eece3747a 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -730,6 +730,7 @@ class PackDeductionScope { void addPack(unsigned Index) { // Save the deduced template argument for the parameter pack expanded // by this pack expansion, then clear out the deduction. + DeducedFromEarlierParameter = !Deduced[Index].isNull(); DeducedPack Pack(Index); Pack.Saved = Deduced[Index]; Deduced[Index] = TemplateArgument(); @@ -858,6 +859,29 @@ class PackDeductionScope { Info.PendingDeducedPacks[Pack.Index] = Pack.Outer; } + std::optional<unsigned> getSavedPackSize(unsigned Index, + TemplateArgument Pattern) const { + + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + S.collectUnexpandedParameterPacks(Pattern, Unexpanded); + if (Unexpanded.size() == 0 || + Packs[0].Saved.getKind() != clang::TemplateArgument::Pack) + return {}; + unsigned PackSize = Packs[0].Saved.pack_size(); + + if (std::all_of(Packs.begin() + 1, Packs.end(), + [&PackSize](auto P) { + return P.Saved.getKind() == TemplateArgument::Pack && + P.Saved.pack_size() == PackSize; + })) + return PackSize; + return {}; + } + + /// Determine whether this pack has already been deduced from a previous + /// argument. + bool isDeducedFromEarlierParameter() const {return DeducedFromEarlierParameter;} + /// Determine whether this pack has already been partially expanded into a /// sequence of (prior) function parameters / template arguments. bool isPartiallyExpanded() { return IsPartiallyExpanded; } @@ -970,7 +994,6 @@ class PackDeductionScope { NewPack = Pack.DeferredDeduction; Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack); } - NamedDecl *Param = TemplateParams->getParam(Pack.Index); if (Result.isNull()) { Info.Param = makeTemplateParameter(Param); @@ -1003,9 +1026,12 @@ class PackDeductionScope { unsigned PackElements = 0; bool IsPartiallyExpanded = false; bool DeducePackIfNotAlreadyDeduced = false; + bool DeducedFromEarlierParameter = false; + /// The number of expansions, if we have a fully-expanded pack in this scope. std::optional<unsigned> FixedNumExpansions; + SmallVector<DeducedPack, 2> Packs; }; @@ -4371,6 +4397,41 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // corresponding argument is a list? PackScope.nextPackElement(); } + } else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() && + PackScope.isDeducedFromEarlierParameter() && + !isa<PackExpansionType>(ParamTypes[ParamIdx + 1])) { + // [temp.deduct.general#3] + // When all template arguments have been deduced + // or obtained from default template arguments, all uses of template + // parameters in the template parameter list of the template are + // replaced with the corresponding deduced or default argument values + // + // If we have a trailing parameter pack, that has been deduced perviously + // we substitute the pack here in a similar fashion as seen above with + // the trailing parameter packs. The main difference here is that, in + // this case we are not processing all of the remaining arguments. We + // are only process as many arguments as much we have in the already + // deduced parameter. + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + collectUnexpandedParameterPacks(ParamPattern, Unexpanded); + if (Unexpanded.size() == 0) + continue; + + std::optional<unsigned> ArgPosAfterSubstitution = + PackScope.getSavedPackSize(getDepthAndIndex(Unexpanded[0]).second, + ParamPattern); + if (!ArgPosAfterSubstitution) + continue; + + unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution; + for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) { + ParamTypesForArgChecking.push_back(ParamPattern); + if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx, + /*ExplicitObjetArgument=*/false)) + return Result; + + PackScope.nextPackElement(); + } } } From 59a01f3be41a1d8efa11e0e31448887b55178f78 Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Wed, 24 Jan 2024 22:33:02 +0100 Subject: [PATCH 02/16] Format changes --- clang/lib/Sema/SemaTemplateDeduction.cpp | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 46fa9eece3747a..e682ca6dc0f7d4 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -869,18 +869,19 @@ class PackDeductionScope { return {}; unsigned PackSize = Packs[0].Saved.pack_size(); - if (std::all_of(Packs.begin() + 1, Packs.end(), - [&PackSize](auto P) { - return P.Saved.getKind() == TemplateArgument::Pack && - P.Saved.pack_size() == PackSize; - })) + if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](auto P) { + return P.Saved.getKind() == TemplateArgument::Pack && + P.Saved.pack_size() == PackSize; + })) return PackSize; return {}; } /// Determine whether this pack has already been deduced from a previous /// argument. - bool isDeducedFromEarlierParameter() const {return DeducedFromEarlierParameter;} + bool isDeducedFromEarlierParameter() const { + return DeducedFromEarlierParameter; + } /// Determine whether this pack has already been partially expanded into a /// sequence of (prior) function parameters / template arguments. @@ -4406,12 +4407,12 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // parameters in the template parameter list of the template are // replaced with the corresponding deduced or default argument values // - // If we have a trailing parameter pack, that has been deduced perviously - // we substitute the pack here in a similar fashion as seen above with - // the trailing parameter packs. The main difference here is that, in - // this case we are not processing all of the remaining arguments. We - // are only process as many arguments as much we have in the already - // deduced parameter. + // If we have a trailing parameter pack, that has been deduced + // perviously we substitute the pack here in a similar fashion as seen + // above with the trailing parameter packs. The main difference here is + // that, in this case we are not processing all of the remaining + // arguments. We are only process as many arguments as much we have in + // the already deduced parameter. SmallVector<UnexpandedParameterPack, 2> Unexpanded; collectUnexpandedParameterPacks(ParamPattern, Unexpanded); if (Unexpanded.size() == 0) From c7aaaadb76e87fc4616e809a91ab80d8ac7a461d Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 08:22:29 +0100 Subject: [PATCH 03/16] Adjust test case and format --- clang/lib/Sema/SemaTemplateDeduction.cpp | 3 +-- .../temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e682ca6dc0f7d4..7df522b93324b7 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -995,6 +995,7 @@ class PackDeductionScope { NewPack = Pack.DeferredDeduction; Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack); } + NamedDecl *Param = TemplateParams->getParam(Pack.Index); if (Result.isNull()) { Info.Param = makeTemplateParameter(Param); @@ -1028,11 +1029,9 @@ class PackDeductionScope { bool IsPartiallyExpanded = false; bool DeducePackIfNotAlreadyDeduced = false; bool DeducedFromEarlierParameter = false; - /// The number of expansions, if we have a fully-expanded pack in this scope. std::optional<unsigned> FixedNumExpansions; - SmallVector<DeducedPack, 2> Packs; }; diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp index 1da599ed3c27aa..2ac66b5055ffd5 100644 --- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp @@ -81,7 +81,7 @@ void test_pair_deduction(int *ip, float *fp, double *dp) { template<typename ...Types> struct tuple { }; template<typename ...Types> -void pack_not_at_end(tuple<Types...>, Types... values, int); // expected-note {{<int *, double *> vs. <>}} +void pack_not_at_end(tuple<Types...>, Types... values, int); // expected-note {{<int *, double *> vs. <int, int>}} void test_pack_not_at_end(tuple<int*, double*> t2) { pack_not_at_end(t2, 0, 0, 0); // expected-error {{no match}} From d3cdcc3b83226d38b9f5955315e28315d3e11fb2 Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 08:36:02 +0100 Subject: [PATCH 04/16] Add tests --- clang/test/SemaTemplate/deduction.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp index ad98de61d9e127..5f18471becc9e8 100644 --- a/clang/test/SemaTemplate/deduction.cpp +++ b/clang/test/SemaTemplate/deduction.cpp @@ -13,6 +13,17 @@ struct X0<int, A> { static const unsigned value = 1; }; +template<class T> +struct type_identity { + using type = T; +}; + +template<class T> +using type_identity_t = typename type_identity<T>::type; + +template <typename... T> +struct args_tag {}; + template<int> struct X0i; template<long> struct X0l; int array_x0a[X0<long, X0l>::value == 0? 1 : -1]; @@ -431,6 +442,17 @@ namespace deduction_after_explicit_pack { i<int, int>(0, 1, 2, 3, 4, 5); // expected-error {{no match}} } + template <typename... T> + void bar(args_tag<T...>, type_identity_t<T>..., int mid, type_identity_t<T>...) {} + void call_bar() { + bar(args_tag<int, int>{}, 4, 8, 1001, 16, 23); + } + template <typename... Y, typename... T> + void foo(args_tag<Y...>, args_tag<T...>, type_identity_t<T>..., int mid, type_identity_t<T>...) {} + void call_foo() { + foo(args_tag<const int,const int, const int>{}, args_tag<int, int, int>{}, 4, 8, 9, 15, 16, 23, 1); + } + // GCC alarmingly accepts this by deducing T={int} by matching the second // parameter against the first argument, then passing the first argument // through the first parameter. From 155e13325487ffc161d7c827b41812aa7ade45e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Spaits?= <48805437+spa...@users.noreply.github.com> Date: Thu, 25 Jan 2024 11:05:42 +0100 Subject: [PATCH 05/16] Fix typo Co-authored-by: cor3ntin <corentinja...@gmail.com> --- clang/lib/Sema/SemaTemplateDeduction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 7df522b93324b7..15c5a30371994d 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4407,7 +4407,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // replaced with the corresponding deduced or default argument values // // If we have a trailing parameter pack, that has been deduced - // perviously we substitute the pack here in a similar fashion as seen + // previously we substitute the pack here in a similar fashion as seen // above with the trailing parameter packs. The main difference here is // that, in this case we are not processing all of the remaining // arguments. We are only process as many arguments as much we have in From e4861624acea1ac4d863d13458d6d9aacd88010c Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 11:51:15 +0100 Subject: [PATCH 06/16] Fix typo #2 --- clang/lib/Sema/SemaTemplateDeduction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 15c5a30371994d..e3eed657e93f1d 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4407,7 +4407,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // replaced with the corresponding deduced or default argument values // // If we have a trailing parameter pack, that has been deduced - // previously we substitute the pack here in a similar fashion as seen + // previously we substitute the pack here in a similar fashion as // above with the trailing parameter packs. The main difference here is // that, in this case we are not processing all of the remaining // arguments. We are only process as many arguments as much we have in From 018deaaa8c9220f7169131707b853fd3bffdb36f Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 13:46:52 +0100 Subject: [PATCH 07/16] Substitue pack even when no separator between packs --- clang/lib/Sema/SemaTemplateDeduction.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e3eed657e93f1d..0b04a66ce9d3f8 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4398,8 +4398,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( PackScope.nextPackElement(); } } else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() && - PackScope.isDeducedFromEarlierParameter() && - !isa<PackExpansionType>(ParamTypes[ParamIdx + 1])) { + PackScope.isDeducedFromEarlierParameter()) { // [temp.deduct.general#3] // When all template arguments have been deduced // or obtained from default template arguments, all uses of template From 486fffeae26a07aa266b8d7e7277728f84bceba0 Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 18:13:05 +0100 Subject: [PATCH 08/16] Use assertion where we know that pack is not empty --- clang/lib/Sema/SemaTemplateDeduction.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 0b04a66ce9d3f8..0194f2da75f01e 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4413,8 +4413,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // the already deduced parameter. SmallVector<UnexpandedParameterPack, 2> Unexpanded; collectUnexpandedParameterPacks(ParamPattern, Unexpanded); - if (Unexpanded.size() == 0) - continue; + assert(Unexpanded.size() != 0 && "We must have an unexpanded pack\n"); std::optional<unsigned> ArgPosAfterSubstitution = PackScope.getSavedPackSize(getDepthAndIndex(Unexpanded[0]).second, From 33336a75c5ef55c1bafbfda6fe642c190a9bd03d Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 18:56:30 +0100 Subject: [PATCH 09/16] Simplify logic for pack size computing --- clang/lib/Sema/SemaTemplateDeduction.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 0194f2da75f01e..808b307729835e 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -859,12 +859,9 @@ class PackDeductionScope { Info.PendingDeducedPacks[Pack.Index] = Pack.Outer; } - std::optional<unsigned> getSavedPackSize(unsigned Index, - TemplateArgument Pattern) const { - - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - S.collectUnexpandedParameterPacks(Pattern, Unexpanded); - if (Unexpanded.size() == 0 || + // Return the size of the saved packs if all of them has the same size. + std::optional<unsigned> getSavedPackSizeIfAllEqual() const { + if (Packs.size() == 0 || Packs[0].Saved.getKind() != clang::TemplateArgument::Pack) return {}; unsigned PackSize = Packs[0].Saved.pack_size(); @@ -4411,13 +4408,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // that, in this case we are not processing all of the remaining // arguments. We are only process as many arguments as much we have in // the already deduced parameter. - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - collectUnexpandedParameterPacks(ParamPattern, Unexpanded); - assert(Unexpanded.size() != 0 && "We must have an unexpanded pack\n"); - std::optional<unsigned> ArgPosAfterSubstitution = - PackScope.getSavedPackSize(getDepthAndIndex(Unexpanded[0]).second, - ParamPattern); + PackScope.getSavedPackSizeIfAllEqual(); if (!ArgPosAfterSubstitution) continue; From 47f86afe1aadeeff18c8b254f7a39c70d733c242 Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 19:14:58 +0100 Subject: [PATCH 10/16] Add a test case for deduction without separator --- clang/test/SemaTemplate/deduction.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp index 5f18471becc9e8..b7988648431c67 100644 --- a/clang/test/SemaTemplate/deduction.cpp +++ b/clang/test/SemaTemplate/deduction.cpp @@ -447,12 +447,18 @@ namespace deduction_after_explicit_pack { void call_bar() { bar(args_tag<int, int>{}, 4, 8, 1001, 16, 23); } + template <typename... Y, typename... T> void foo(args_tag<Y...>, args_tag<T...>, type_identity_t<T>..., int mid, type_identity_t<T>...) {} void call_foo() { foo(args_tag<const int,const int, const int>{}, args_tag<int, int, int>{}, 4, 8, 9, 15, 16, 23, 1); } + template <typename... Y, typename... T> void baz(args_tag<T...>, T..., T...) {} + void call_baz() { + baz(args_tag<int, int>{}, 1, 2, 3, 4); + } + // GCC alarmingly accepts this by deducing T={int} by matching the second // parameter against the first argument, then passing the first argument // through the first parameter. From 8705e03356d289e659ed843208afff1f2b49435f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Spaits?= <48805437+spa...@users.noreply.github.com> Date: Thu, 25 Jan 2024 20:16:33 +0100 Subject: [PATCH 11/16] Add const to lambda parameter Co-authored-by: Erich Keane <eke...@nvidia.com> --- clang/lib/Sema/SemaTemplateDeduction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 808b307729835e..9f11c4614fbed6 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -866,7 +866,7 @@ class PackDeductionScope { return {}; unsigned PackSize = Packs[0].Saved.pack_size(); - if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](auto P) { + if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](const auto &P) { return P.Saved.getKind() == TemplateArgument::Pack && P.Saved.pack_size() == PackSize; })) From 01dab7dc9a3b5eff32777b36b316f3f6a73b403b Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 20:37:42 +0100 Subject: [PATCH 12/16] Update release notes --- clang/docs/ReleaseNotes.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5330cd9caad801..8d2c47612ec301 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -70,7 +70,9 @@ C++2c Feature Support Resolutions to C++ Defect Reports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +- Substitute template parameter pack, when it is not explicitly specified + in the template parameters, but is deduced from a previous argument. + (`#78449: <https://github.com/llvm/llvm-project/issues/78449>`_). C Language Changes ------------------ From fdf3a00aba578995ca29a0028009a2fb2c91f40a Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Thu, 25 Jan 2024 20:51:57 +0100 Subject: [PATCH 13/16] Fix formatting od release notes --- clang/docs/ReleaseNotes.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8d2c47612ec301..f4393f6bd96c87 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -73,6 +73,7 @@ Resolutions to C++ Defect Reports - Substitute template parameter pack, when it is not explicitly specified in the template parameters, but is deduced from a previous argument. (`#78449: <https://github.com/llvm/llvm-project/issues/78449>`_). + C Language Changes ------------------ From 4c36190bbcdbc5b40a640d7460951a1724231cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Spaits?= <48805437+spa...@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:27:31 +0100 Subject: [PATCH 14/16] Fix grammar mistake Co-authored-by: cor3ntin <corentinja...@gmail.com> --- clang/lib/Sema/SemaTemplateDeduction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 9f11c4614fbed6..b12a0da55005fc 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4406,7 +4406,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // previously we substitute the pack here in a similar fashion as // above with the trailing parameter packs. The main difference here is // that, in this case we are not processing all of the remaining - // arguments. We are only process as many arguments as much we have in + // arguments. We are only process as many arguments as we have in // the already deduced parameter. std::optional<unsigned> ArgPosAfterSubstitution = PackScope.getSavedPackSizeIfAllEqual(); From 74ec3b3da7dcbd854a8300f87c7e88f47c3661c8 Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Fri, 26 Jan 2024 15:35:43 +0100 Subject: [PATCH 15/16] Add new test case --- clang/test/SemaTemplate/deduction.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp index b7988648431c67..e18551bf030222 100644 --- a/clang/test/SemaTemplate/deduction.cpp +++ b/clang/test/SemaTemplate/deduction.cpp @@ -454,6 +454,12 @@ namespace deduction_after_explicit_pack { foo(args_tag<const int,const int, const int>{}, args_tag<int, int, int>{}, 4, 8, 9, 15, 16, 23, 1); } + template <typename... Y, typename... T> + void foo2(args_tag<Y...>, args_tag<T...>, type_identity_t<T>..., type_identity_t<T>...) {} + void call_foo2() { + foo2(args_tag<const int,const int, const int>{}, args_tag<int, int, int>{}, 4, 8, 9, 15, 16, 23); + } + template <typename... Y, typename... T> void baz(args_tag<T...>, T..., T...) {} void call_baz() { baz(args_tag<int, int>{}, 1, 2, 3, 4); From 400cdecb408f611eb144c61675ad75ca15f91e1c Mon Sep 17 00:00:00 2001 From: Gabor Spaits <gaborspai...@gmail.com> Date: Fri, 26 Jan 2024 22:38:30 +0100 Subject: [PATCH 16/16] Add test cases and remove redundant conditions --- clang/lib/Sema/SemaTemplateDeduction.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index b12a0da55005fc..0de934395ef519 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -861,14 +861,10 @@ class PackDeductionScope { // Return the size of the saved packs if all of them has the same size. std::optional<unsigned> getSavedPackSizeIfAllEqual() const { - if (Packs.size() == 0 || - Packs[0].Saved.getKind() != clang::TemplateArgument::Pack) - return {}; unsigned PackSize = Packs[0].Saved.pack_size(); if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](const auto &P) { - return P.Saved.getKind() == TemplateArgument::Pack && - P.Saved.pack_size() == PackSize; + return P.Saved.pack_size() == PackSize; })) return PackSize; return {}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits