Cherry-picked in e241c8fe6d2e6d83e9fb32bd34da8ffcdc0dd83d. Thanks!
On Thu, Jan 16, 2020 at 1:22 AM Richard Smith <rich...@metafoo.co.uk> wrote: > > Hi Hans, > > Please consider this bugfix for the Clang 10 release branch. > > On Wed, 15 Jan 2020 at 16:21, Richard Smith via cfe-commits > <cfe-commits@lists.llvm.org> wrote: >> >> >> Author: Richard Smith >> Date: 2020-01-15T16:21:08-08:00 >> New Revision: e8f198dd9e9dabed8d50276465906e7c8827cada >> >> URL: >> https://github.com/llvm/llvm-project/commit/e8f198dd9e9dabed8d50276465906e7c8827cada >> DIFF: >> https://github.com/llvm/llvm-project/commit/e8f198dd9e9dabed8d50276465906e7c8827cada.diff >> >> LOG: Fix pack deduction to only deduce the arity of packs that are actually >> expanded by the deduced pack. >> >> We recently started also deducing the arity of separately-expanded packs >> that are merely mentioned within the pack in question, which is >> incorrect. >> >> Added: >> >> >> Modified: >> clang/lib/Sema/SemaTemplateDeduction.cpp >> clang/test/SemaTemplate/deduction.cpp >> >> Removed: >> >> >> >> ################################################################################ >> diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp >> b/clang/lib/Sema/SemaTemplateDeduction.cpp >> index 1b9f1b2144d1..048a50a741e4 100644 >> --- a/clang/lib/Sema/SemaTemplateDeduction.cpp >> +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp >> @@ -724,38 +724,48 @@ class PackDeductionScope { >> // Compute the set of template parameter indices that correspond to >> // parameter packs expanded by the pack expansion. >> llvm::SmallBitVector SawIndices(TemplateParams->size()); >> + llvm::SmallVector<TemplateArgument, 4> ExtraDeductions; >> >> auto AddPack = [&](unsigned Index) { >> if (SawIndices[Index]) >> return; >> SawIndices[Index] = true; >> addPack(Index); >> + >> + // Deducing a parameter pack that is a pack expansion also constrains >> the >> + // packs appearing in that parameter to have the same deduced arity. >> Also, >> + // in C++17 onwards, deducing a non-type template parameter deduces >> its >> + // type, so we need to collect the pending deduced values for those >> packs. >> + if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>( >> + TemplateParams->getParam(Index))) { >> + if (auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType())) >> + ExtraDeductions.push_back(Expansion->getPattern()); >> + } >> + // FIXME: Also collect the unexpanded packs in any type and template >> + // parameter packs that are pack expansions. >> }; >> >> - // First look for unexpanded packs in the pattern. >> - SmallVector<UnexpandedParameterPack, 2> Unexpanded; >> - S.collectUnexpandedParameterPacks(Pattern, Unexpanded); >> - for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { >> - unsigned Depth, Index; >> - std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]); >> - if (Depth == Info.getDeducedDepth()) >> - AddPack(Index); >> - } >> + auto Collect = [&](TemplateArgument Pattern) { >> + SmallVector<UnexpandedParameterPack, 2> Unexpanded; >> + S.collectUnexpandedParameterPacks(Pattern, Unexpanded); >> + for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { >> + unsigned Depth, Index; >> + std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]); >> + if (Depth == Info.getDeducedDepth()) >> + AddPack(Index); >> + } >> + }; >> + >> + // Look for unexpanded packs in the pattern. >> + Collect(Pattern); >> assert(!Packs.empty() && "Pack expansion without unexpanded packs?"); >> >> unsigned NumNamedPacks = Packs.size(); >> >> - // We can also have deduced template parameters that do not actually >> - // appear in the pattern, but can be deduced by it (the type of a >> non-type >> - // template parameter pack, in particular). These won't have prevented >> us >> - // from partially expanding the pack. >> - llvm::SmallBitVector Used(TemplateParams->size()); >> - MarkUsedTemplateParameters(S.Context, Pattern, /*OnlyDeduced*/true, >> - Info.getDeducedDepth(), Used); >> - for (int Index = Used.find_first(); Index != -1; >> - Index = Used.find_next(Index)) >> - if (TemplateParams->getParam(Index)->isParameterPack()) >> - AddPack(Index); >> + // Also look for unexpanded packs that are indirectly deduced by >> deducing >> + // the sizes of the packs in this pattern. >> + while (!ExtraDeductions.empty()) >> + Collect(ExtraDeductions.pop_back_val()); >> >> return NumNamedPacks; >> } >> >> diff --git a/clang/test/SemaTemplate/deduction.cpp >> b/clang/test/SemaTemplate/deduction.cpp >> index 1f1c30a8b4ab..7268912dd6c5 100644 >> --- a/clang/test/SemaTemplate/deduction.cpp >> +++ b/clang/test/SemaTemplate/deduction.cpp >> @@ -546,3 +546,21 @@ namespace designators { >> >> static_assert(f({.a = 1, .b = 2}) == 3, ""); // expected-error {{no >> matching function}} >> } >> + >> +namespace nested_packs { >> + template<typename ...T, typename ...U> void f(T (*...f)(U...)); // >> expected-note {{deduced packs of >> diff erent lengths for parameter 'U' (<> vs. <int>)}} >> + void g() { f(g); f(g, g); f(g, g, g); } >> + void h(int) { f(h); f(h, h); f(h, h, h); } >> + void i() { f(g, h); } // expected-error {{no matching function}} >> + >> +#if __cplusplus >= 201703L >> + template<auto ...A> struct Q {}; >> + template<typename ...T, T ...A, T ...B> void q(Q<A...>, Q<B...>); // #q >> + void qt(Q<> q0, Q<1, 2> qii, Q<1, 2, 3> qiii) { >> + q(q0, q0); >> + q(qii, qii); >> + q(qii, qiii); // expected-error {{no match}} expected-note@#q {{deduced >> packs of >> diff erent lengths for parameter 'T' (<int, int> vs. <int, int, int>)}} >> + q(q0, qiii); // expected-error {{no match}} expected-note@#q {{deduced >> packs of >> diff erent lengths for parameter 'T' (<> vs. <int, int, int>)}} >> + } >> +#endif >> +} >> >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits