================ @@ -5570,61 +5570,73 @@ bool Sema::CheckTemplateArgumentList( } if (ArgIdx < NumArgs) { - // Check the template argument we were given. - if (CheckTemplateArgument(*Param, NewArgs[ArgIdx], Template, TemplateLoc, - RAngleLoc, SugaredArgumentPack.size(), - SugaredConverted, CanonicalConverted, - CTAK_Specified, /*PartialOrdering=*/false, - MatchedPackOnParmToNonPackOnArg)) - return true; - - CanonicalConverted.back().setIsDefaulted( - clang::isSubstitutedDefaultArgument( - Context, NewArgs[ArgIdx].getArgument(), *Param, - CanonicalConverted, Params->getDepth())); - - bool PackExpansionIntoNonPack = - NewArgs[ArgIdx].getArgument().isPackExpansion() && - (!(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param)); - // CWG1430: Don't diagnose this pack expansion when partial - // ordering template template parameters. Some uses of the template could - // be valid, and invalid uses will be diagnosed later during - // instantiation. - if (PackExpansionIntoNonPack && !PartialOrderingTTP && - (isa<TypeAliasTemplateDecl>(Template) || - isa<ConceptDecl>(Template))) { - // CWG1430: we have a pack expansion as an argument to an - // alias template, and it's not part of a parameter pack. This - // can't be canonicalized, so reject it now. - // As for concepts - we cannot normalize constraints where this - // situation exists. - Diag(NewArgs[ArgIdx].getLocation(), - diag::err_template_expansion_into_fixed_list) - << (isa<ConceptDecl>(Template) ? 1 : 0) - << NewArgs[ArgIdx].getSourceRange(); - NoteTemplateParameterLocation(**Param); - return true; + TemplateArgumentLoc &ArgLoc = NewArgs[ArgIdx]; + bool NonPackParameter = + !(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param); + bool ArgIsExpansion = ArgLoc.getArgument().isPackExpansion(); + + if (ArgIsExpansion && PartialOrderingTTP) { + unsigned Num = ParamEnd - Param; + MutableArrayRef<TemplateArgument> Args = { + Context.Allocate<TemplateArgument>(Num), Num}; + + for (TemplateParameterList::iterator First = Param; Param != ParamEnd; + ++Param) { + TemplateArgument &Arg = Args[Param - First]; + Arg = ArgLoc.getArgument(); + if (!(*Param)->isTemplateParameterPack() || + getExpandedPackSize(*Param)) + Arg = Arg.getPackExpansionPattern(); + TemplateArgumentLoc NewArgLoc(Arg, ArgLoc.getLocInfo()); + if (CheckTemplateArgument(*Param, NewArgLoc, Template, TemplateLoc, + RAngleLoc, SugaredArgumentPack.size(), + SugaredConverted, CanonicalConverted, + CTAK_Specified, /*PartialOrdering=*/false, + MatchedPackOnParmToNonPackOnArg)) ---------------- mizvekov wrote:
Yes I thought about that, but the current approach saves one extra allocation and copy for the simple cases where the match is valid and the program is well formed. Since Args is allocated in the ASTContext, there we don't usually care about "leaks" in ill-formed cases. Granted in partial ordering / SFINAE context, the program could still be well-formed, but that still subject to the same code paths as ill-formed cases. I think in this particular case, the change is so minuscule I wouldn't mind the change to a SmallVector though. https://github.com/llvm/llvm-project/pull/124137 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits