[clang] e8f198d - Fix pack deduction to only deduce the arity of packs that are actually

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 15 16:22:02 PST 2020


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 at 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 at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200115/35f21669/attachment-0001.html>


More information about the cfe-commits mailing list