@@ -5502,7 +5502,8 @@ bool Sema::CheckTemplateArgumentList(
55025502 DefaultArgs && ParamIdx >= DefaultArgs.StartPos ) {
55035503 // All written arguments should have been consumed by this point.
55045504 assert (ArgIdx == NumArgs && " bad default argument deduction" );
5505- if (ParamIdx == DefaultArgs.StartPos ) {
5505+ // FIXME: Don't ignore parameter packs.
5506+ if (ParamIdx == DefaultArgs.StartPos && !(*Param)->isParameterPack ()) {
55065507 assert (Param + DefaultArgs.Args .size () <= ParamEnd);
55075508 // Default arguments from a DeducedTemplateName are already converted.
55085509 for (const TemplateArgument &DefArg : DefaultArgs.Args ) {
@@ -5727,9 +5728,8 @@ bool Sema::CheckTemplateArgumentList(
57275728 // pack expansions; they might be empty. This can happen even if
57285729 // PartialTemplateArgs is false (the list of arguments is complete but
57295730 // still dependent).
5730- if (PartialOrderingTTP ||
5731- (CurrentInstantiationScope &&
5732- CurrentInstantiationScope->getPartiallySubstitutedPack ())) {
5731+ if (ArgIdx < NumArgs && CurrentInstantiationScope &&
5732+ CurrentInstantiationScope->getPartiallySubstitutedPack ()) {
57335733 while (ArgIdx < NumArgs &&
57345734 NewArgs[ArgIdx].getArgument ().isPackExpansion ()) {
57355735 const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument ();
@@ -7327,46 +7327,64 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
73277327 << Template;
73287328 }
73297329
7330- if (!getLangOpts ().RelaxedTemplateTemplateArgs )
7331- return !TemplateParameterListsAreEqual (
7332- Template->getTemplateParameters (), Params, /* Complain=*/ true ,
7333- TPL_TemplateTemplateArgumentMatch, Arg.getLocation ());
7334-
73357330 // C++1z [temp.arg.template]p3: (DR 150)
73367331 // A template-argument matches a template template-parameter P when P
73377332 // is at least as specialized as the template-argument A.
7338- if (!isTemplateTemplateParameterAtLeastAsSpecializedAs (
7339- Params, Param, Template, DefaultArgs, Arg.getLocation (), IsDeduced))
7340- return true ;
7341- // P2113
7342- // C++20[temp.func.order]p2
7343- // [...] If both deductions succeed, the partial ordering selects the
7344- // more constrained template (if one exists) as determined below.
7345- SmallVector<const Expr *, 3 > ParamsAC, TemplateAC;
7346- Params->getAssociatedConstraints (ParamsAC);
7347- // C++20[temp.arg.template]p3
7348- // [...] In this comparison, if P is unconstrained, the constraints on A
7349- // are not considered.
7350- if (ParamsAC.empty ())
7351- return false ;
7333+ if (getLangOpts ().RelaxedTemplateTemplateArgs ) {
7334+ // Quick check for the common case:
7335+ // If P contains a parameter pack, then A [...] matches P if each of A's
7336+ // template parameters matches the corresponding template parameter in
7337+ // the template-parameter-list of P.
7338+ if (TemplateParameterListsAreEqual (
7339+ Template->getTemplateParameters (), Params, false ,
7340+ TPL_TemplateTemplateArgumentMatch, Arg.getLocation ()) &&
7341+ // If the argument has no associated constraints, then the parameter is
7342+ // definitely at least as specialized as the argument.
7343+ // Otherwise - we need a more thorough check.
7344+ !Template->hasAssociatedConstraints ())
7345+ return false ;
73527346
7353- Template->getAssociatedConstraints (TemplateAC);
7347+ if (isTemplateTemplateParameterAtLeastAsSpecializedAs (
7348+ Params, Template, DefaultArgs, Arg.getLocation (), IsDeduced)) {
7349+ // P2113
7350+ // C++20[temp.func.order]p2
7351+ // [...] If both deductions succeed, the partial ordering selects the
7352+ // more constrained template (if one exists) as determined below.
7353+ SmallVector<const Expr *, 3 > ParamsAC, TemplateAC;
7354+ Params->getAssociatedConstraints (ParamsAC);
7355+ // C++2a[temp.arg.template]p3
7356+ // [...] In this comparison, if P is unconstrained, the constraints on A
7357+ // are not considered.
7358+ if (ParamsAC.empty ())
7359+ return false ;
73547360
7355- bool IsParamAtLeastAsConstrained;
7356- if (IsAtLeastAsConstrained (Param, ParamsAC, Template, TemplateAC,
7357- IsParamAtLeastAsConstrained))
7358- return true ;
7359- if (!IsParamAtLeastAsConstrained) {
7360- Diag (Arg.getLocation (),
7361- diag::err_template_template_parameter_not_at_least_as_constrained)
7362- << Template << Param << Arg.getSourceRange ();
7363- Diag (Param->getLocation (), diag::note_entity_declared_at) << Param;
7364- Diag (Template->getLocation (), diag::note_entity_declared_at) << Template;
7365- MaybeEmitAmbiguousAtomicConstraintsDiagnostic (Param, ParamsAC, Template,
7366- TemplateAC);
7367- return true ;
7361+ Template->getAssociatedConstraints (TemplateAC);
7362+
7363+ bool IsParamAtLeastAsConstrained;
7364+ if (IsAtLeastAsConstrained (Param, ParamsAC, Template, TemplateAC,
7365+ IsParamAtLeastAsConstrained))
7366+ return true ;
7367+ if (!IsParamAtLeastAsConstrained) {
7368+ Diag (Arg.getLocation (),
7369+ diag::err_template_template_parameter_not_at_least_as_constrained)
7370+ << Template << Param << Arg.getSourceRange ();
7371+ Diag (Param->getLocation (), diag::note_entity_declared_at) << Param;
7372+ Diag (Template->getLocation (), diag::note_entity_declared_at)
7373+ << Template;
7374+ MaybeEmitAmbiguousAtomicConstraintsDiagnostic (Param, ParamsAC, Template,
7375+ TemplateAC);
7376+ return true ;
7377+ }
7378+ return false ;
7379+ }
7380+ // FIXME: Produce better diagnostics for deduction failures.
73687381 }
7369- return false ;
7382+
7383+ return !TemplateParameterListsAreEqual (Template->getTemplateParameters (),
7384+ Params,
7385+ true ,
7386+ TPL_TemplateTemplateArgumentMatch,
7387+ Arg.getLocation ());
73707388}
73717389
73727390static Sema::SemaDiagnosticBuilder noteLocation (Sema &S, const NamedDecl &Decl,
0 commit comments