Repository: llvm/llvm-project
File: clang/lib/Sema/SemaTemplate.cpp (C++)

Code before:
          if (CheckTemplateArgument(*Param, NewArgLoc, Template, TemplateLoc,
                                    RAngleLoc, SugaredArgumentPack.size(), CTAI,
                                    CTAK_Specified))
            return true;
          Arg = NewArgLoc.getArgument();
          CTAI.CanonicalConverted.back().setIsDefaulted(
              clang::isSubstitutedDefaultArgument(Context, Arg, *Param,
                                                  CTAI.CanonicalConverted,
                                                  Params->getDepth()));
        }
        ArgLoc =
            TemplateArgumentLoc(TemplateArgument::CreatePackCopy(Context, Args),
                                ArgLoc.getLocInfo());
      } else {
        SaveAndRestore _1(CTAI.PartialOrdering, false);
        if (CheckTemplateArgument(*Param, ArgLoc, Template, TemplateLoc,
                                  RAngleLoc, SugaredArgumentPack.size(), CTAI,
                                  CTAK_Specified))
          return true;
        CTAI.CanonicalConverted.back().setIsDefaulted(
            clang::isSubstitutedDefaultArgument(Context, ArgLoc.getArgument(),
                                                *Param, CTAI.CanonicalConverted,
                                                Params->getDepth()));
        if (ArgIsExpansion && NonPackParameter) {
          // CWG1430/CWG2686: we have a pack expansion as an argument to an
          // alias template or concept, and it's not part of a parameter pack.
          // This can't be canonicalized, so reject it now.
          if (isa<TypeAliasTemplateDecl, ConceptDecl, BuiltinTemplateDecl>(
                  Template)) {
            unsigned DiagSelect = isa<ConceptDecl>(Template)           ? 1
                                  : isa<BuiltinTemplateDecl>(Template) ? 2
                                                                       : 0;
            Diag(ArgLoc.getLocation(),
                 diag::err_template_expansion_into_fixed_list)
                << DiagSelect << ArgLoc.getSourceRange();
            NoteTemplateParameterLocation(**Param);
            return true;
          }
        }
      }

      // We're now done with this argument.
      ++ArgIdx;

      if (ArgIsExpansion && (CTAI.MatchingTTP || NonPackParameter)) {
        // Directly convert the remaining arguments, because we don't know what
        // parameters they'll match up with.

        if (!SugaredArgumentPack.empty()) {
          // If we were part way through filling in an expanded parameter pack,
          // fall back to just producing individual arguments.

Review comment (suggestion):
```suggestion
          // alias template, builtin template, or concept, and it's not part of a parameter pack.
```

Code after:
              getExpandedPackSize(*Param))
            Arg = Arg.getPackExpansionPattern();
          TemplateArgumentLoc NewArgLoc(Arg, ArgLoc.getLocInfo());
          SaveAndRestore _1(CTAI.PartialOrdering, false);
          SaveAndRestore _2(CTAI.MatchingTTP, true);
          if (CheckTemplateArgument(*Param, NewArgLoc, Template, TemplateLoc,
                                    RAngleLoc, SugaredArgumentPack.size(), CTAI,
                                    CTAK_Specified))
            return true;
          Arg = NewArgLoc.getArgument();
          CTAI.CanonicalConverted.back().setIsDefaulted(
              clang::isSubstitutedDefaultArgument(Context, Arg, *Param,
                                                  CTAI.CanonicalConverted,
                                                  Params->getDepth()));
        }
        ArgLoc =
            TemplateArgumentLoc(TemplateArgument::CreatePackCopy(Context, Args),
                                ArgLoc.getLocInfo());
      } else {
        SaveAndRestore _1(CTAI.PartialOrdering, false);
        if (CheckTemplateArgument(*Param, ArgLoc, Template, TemplateLoc,
                                  RAngleLoc, SugaredArgumentPack.size(), CTAI,
                                  CTAK_Specified))
          return true;
        CTAI.CanonicalConverted.back().setIsDefaulted(
            clang::isSubstitutedDefaultArgument(Context, ArgLoc.getArgument(),
                                                *Param, CTAI.CanonicalConverted,
                                                Params->getDepth()));
        if (ArgIsExpansion && NonPackParameter) {
          // CWG1430/CWG2686: we have a pack expansion as an argument to an
          // alias template, builtin template, or concept, and it's not part of
          // a parameter pack. This can't be canonicalized, so reject it now.
          if (isa<TypeAliasTemplateDecl, ConceptDecl, BuiltinTemplateDecl>(
                  Template)) {
            unsigned DiagSelect = isa<ConceptDecl>(Template)           ? 1
                                  : isa<BuiltinTemplateDecl>(Template) ? 2
                                                                       : 0;
            Diag(ArgLoc.getLocation(),
                 diag::err_template_expansion_into_fixed_list)
                << DiagSelect << ArgLoc.getSourceRange();
            NoteTemplateParameterLocation(**Param);
            return true;
          }
        }
      }

      // We're now done with this argument.
      ++ArgIdx;

      if (ArgIsExpansion && (CTAI.MatchingTTP || NonPackParameter)) {
        // Directly convert the remaining arguments, because we don't know what