Commit dffdec69 authored by Tom Stellard's avatar Tom Stellard
Browse files

Merging r221832:

------------------------------------------------------------------------
r221832 | richard-llvm | 2014-11-12 18:38:38 -0500 (Wed, 12 Nov 2014) | 5 lines

PR19372: Keep checking template arguments after we see an argument pack
expansion into a parameter pack; we know that we're still filling in that
parameter's arguments. Previously, if we hit this case for an alias template,
we'd try to substitute using non-canonical template arguments.

------------------------------------------------------------------------

llvm-svn: 223719
parent f03c72a5
Loading
Loading
Loading
Loading
+11 −28
Original line number Diff line number Diff line
@@ -3692,12 +3692,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
                                ArgumentPack.size(), Converted))
        return true;

      if (TemplateArgs[ArgIdx].getArgument().isPackExpansion() &&
          isa<TypeAliasTemplateDecl>(Template) &&
          !(Param + 1 == ParamEnd && (*Param)->isTemplateParameterPack() &&
            !getExpandedPackSize(*Param))) {
      bool PackExpansionIntoNonPack =
          TemplateArgs[ArgIdx].getArgument().isPackExpansion() &&
          (!(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param));
      if (PackExpansionIntoNonPack && isa<TypeAliasTemplateDecl>(Template)) {
        // Core issue 1430: we have a pack expansion as an argument to an
        // alias template, and it's not part of a final parameter pack. This
        // alias template, and it's not part of a parameter pack. This
        // can't be canonicalized, so reject it now.
        Diag(TemplateArgs[ArgIdx].getLocation(),
             diag::err_alias_template_expansion_into_fixed_list)
@@ -3720,16 +3720,11 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
        ++Param;
      }

      // If we just saw a pack expansion, then directly convert the remaining
      // arguments, because we don't know what parameters they'll match up
      // with.
      if (TemplateArgs[ArgIdx-1].getArgument().isPackExpansion()) {
        bool InFinalParameterPack = Param != ParamEnd &&
                                    Param + 1 == ParamEnd &&
                                    (*Param)->isTemplateParameterPack() &&
                                    !getExpandedPackSize(*Param);

        if (!InFinalParameterPack && !ArgumentPack.empty()) {
      // If we just saw a pack expansion into a non-pack, then directly convert
      // the remaining arguments, because we don't know what parameters they'll
      // match up with.
      if (PackExpansionIntoNonPack) {
        if (!ArgumentPack.empty()) {
          // If we were part way through filling in an expanded parameter pack,
          // fall back to just producing individual arguments.
          Converted.insert(Converted.end(),
@@ -3738,22 +3733,10 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
        }

        while (ArgIdx < NumArgs) {
          if (InFinalParameterPack)
            ArgumentPack.push_back(TemplateArgs[ArgIdx].getArgument());
          else
          Converted.push_back(TemplateArgs[ArgIdx].getArgument());
          ++ArgIdx;
        }

        // Push the argument pack onto the list of converted arguments.
        if (InFinalParameterPack && !ArgumentPack.empty()) {
          Converted.push_back(
            TemplateArgument::CreatePackCopy(Context,
                                             ArgumentPack.data(),
                                             ArgumentPack.size()));
          ArgumentPack.clear();
        }

        return false;
      }

+14 −0
Original line number Diff line number Diff line
@@ -178,3 +178,17 @@ namespace PR21536 {
  template<typename ...T> void f(S<T...>);
  void g() { f(S<int, int>()); }
}

namespace PR19372 {
  template <template<typename...> class C, typename ...Us> struct BindBack {
    template <typename ...Ts> using apply = C<Ts..., Us...>;
  };
  template <typename, typename...> struct Y;
  template <typename ...Ts> using Z = Y<Ts...>;

  using T = BindBack<Z, int>::apply<>;
  using T = Z<int>;

  using U = BindBack<Z, int, int>::apply<char>;
  using U = Z<char, int, int>;
}