@@ -5502,7 +5502,8 @@ bool Sema::CheckTemplateArgumentList(
5502
5502
DefaultArgs && ParamIdx >= DefaultArgs.StartPos ) {
5503
5503
// All written arguments should have been consumed by this point.
5504
5504
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 ()) {
5506
5507
assert (Param + DefaultArgs.Args .size () <= ParamEnd);
5507
5508
// Default arguments from a DeducedTemplateName are already converted.
5508
5509
for (const TemplateArgument &DefArg : DefaultArgs.Args ) {
@@ -5727,9 +5728,8 @@ bool Sema::CheckTemplateArgumentList(
5727
5728
// pack expansions; they might be empty. This can happen even if
5728
5729
// PartialTemplateArgs is false (the list of arguments is complete but
5729
5730
// still dependent).
5730
- if (PartialOrderingTTP ||
5731
- (CurrentInstantiationScope &&
5732
- CurrentInstantiationScope->getPartiallySubstitutedPack ())) {
5731
+ if (ArgIdx < NumArgs && CurrentInstantiationScope &&
5732
+ CurrentInstantiationScope->getPartiallySubstitutedPack ()) {
5733
5733
while (ArgIdx < NumArgs &&
5734
5734
NewArgs[ArgIdx].getArgument ().isPackExpansion ()) {
5735
5735
const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument ();
@@ -7327,46 +7327,64 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
7327
7327
<< Template;
7328
7328
}
7329
7329
7330
- if (!getLangOpts ().RelaxedTemplateTemplateArgs )
7331
- return !TemplateParameterListsAreEqual (
7332
- Template->getTemplateParameters (), Params, /* Complain=*/ true ,
7333
- TPL_TemplateTemplateArgumentMatch, Arg.getLocation ());
7334
-
7335
7330
// C++1z [temp.arg.template]p3: (DR 150)
7336
7331
// A template-argument matches a template template-parameter P when P
7337
7332
// 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 ;
7352
7346
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 ;
7354
7360
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.
7368
7381
}
7369
- return false ;
7382
+
7383
+ return !TemplateParameterListsAreEqual (Template->getTemplateParameters (),
7384
+ Params,
7385
+ true ,
7386
+ TPL_TemplateTemplateArgumentMatch,
7387
+ Arg.getLocation ());
7370
7388
}
7371
7389
7372
7390
static Sema::SemaDiagnosticBuilder noteLocation (Sema &S, const NamedDecl &Decl,
0 commit comments