@@ -7068,22 +7068,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
70687068
70697069 // If the parameter type somehow involves auto, deduce the type now.
70707070 DeducedType *DeducedT = ParamType->getContainedDeducedType ();
7071- if (getLangOpts ().CPlusPlus17 && DeducedT && !DeducedT->isDeduced ()) {
7072- // During template argument deduction, we allow 'decltype(auto)' to
7073- // match an arbitrary dependent argument.
7074- // FIXME: The language rules don't say what happens in this case.
7075- // FIXME: We get an opaque dependent type out of decltype(auto) if the
7076- // expression is merely instantiation-dependent; is this enough?
7077- if (DeductionArg->isTypeDependent ()) {
7078- auto *AT = dyn_cast<AutoType>(DeducedT);
7079- if (AT && AT->isDecltypeAuto ()) {
7080- SugaredConverted = TemplateArgument (Arg, /* IsCanonical=*/ false );
7081- CanonicalConverted = TemplateArgument (
7082- Context.getCanonicalTemplateArgument (SugaredConverted));
7083- return Arg;
7084- }
7085- }
7086-
7071+ bool IsDeduced = DeducedT && !DeducedT->isDeduced ();
7072+ if (IsDeduced) {
70877073 // When checking a deduced template argument, deduce from its type even if
70887074 // the type is dependent, in order to check the types of non-type template
70897075 // arguments line up properly in partial ordering.
@@ -7112,17 +7098,21 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
71127098 // along with the other associated constraints after
71137099 // checking the template argument list.
71147100 /* IgnoreConstraints=*/ true );
7115- if (Result == TemplateDeductionResult::AlreadyDiagnosed) {
7116- return ExprError ();
7117- } else if (Result != TemplateDeductionResult::Success) {
7118- if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
7119- Diag (Arg->getExprLoc (),
7120- diag::err_non_type_template_parm_type_deduction_failure)
7121- << Param->getDeclName () << NTTP->getType () << Arg->getType ()
7122- << Arg->getSourceRange ();
7101+ if (Result != TemplateDeductionResult::Success) {
7102+ ParamType = TSI->getType ();
7103+ if (StrictCheck || !DeductionArg->isTypeDependent ()) {
7104+ if (Result == TemplateDeductionResult::AlreadyDiagnosed)
7105+ return ExprError ();
7106+ if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param))
7107+ Diag (Arg->getExprLoc (),
7108+ diag::err_non_type_template_parm_type_deduction_failure)
7109+ << Param->getDeclName () << NTTP->getType () << Arg->getType ()
7110+ << Arg->getSourceRange ();
7111+ NoteTemplateParameterLocation (*Param);
7112+ return ExprError ();
71237113 }
7124- NoteTemplateParameterLocation (*Param );
7125- return ExprError ( );
7114+ ParamType = SubstAutoTypeDependent (ParamType );
7115+ assert (!ParamType. isNull () && " substituting DependentTy can't fail " );
71267116 }
71277117 }
71287118 // CheckNonTypeTemplateParameterType will produce a diagnostic if there's
@@ -7144,14 +7134,16 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
71447134 // type-dependent, there's nothing we can check now.
71457135 if (ParamType->isDependentType () || DeductionArg->isTypeDependent ()) {
71467136 // Force the argument to the type of the parameter to maintain invariants.
7147- ExprResult E = ImpCastExprToType (
7148- DeductionArg, ParamType.getNonLValueExprType (Context), CK_Dependent,
7149- ParamType->isLValueReferenceType () ? VK_LValue
7150- : ParamType->isRValueReferenceType () ? VK_XValue
7151- : VK_PRValue);
7152- if (E.isInvalid ())
7153- return ExprError ();
7154- setDeductionArg (E.get ());
7137+ if (!IsDeduced) {
7138+ ExprResult E = ImpCastExprToType (
7139+ DeductionArg, ParamType.getNonLValueExprType (Context), CK_Dependent,
7140+ ParamType->isLValueReferenceType () ? VK_LValue
7141+ : ParamType->isRValueReferenceType () ? VK_XValue
7142+ : VK_PRValue);
7143+ if (E.isInvalid ())
7144+ return ExprError ();
7145+ setDeductionArg (E.get ());
7146+ }
71557147 SugaredConverted = TemplateArgument (Arg, /* IsCanonical=*/ false );
71567148 CanonicalConverted = TemplateArgument (
71577149 Context.getCanonicalTemplateArgument (SugaredConverted));
@@ -8555,6 +8547,7 @@ static SourceRange findTemplateParameter(unsigned Depth, TypeLoc TL) {
85558547static bool CheckNonTypeTemplatePartialSpecializationArgs (
85568548 Sema &S, SourceLocation TemplateNameLoc, NonTypeTemplateParmDecl *Param,
85578549 const TemplateArgument *Args, unsigned NumArgs, bool IsDefaultArgument) {
8550+ bool HasError = false ;
85588551 for (unsigned I = 0 ; I != NumArgs; ++I) {
85598552 if (Args[I].getKind () == TemplateArgument::Pack) {
85608553 if (CheckNonTypeTemplatePartialSpecializationArgs (
@@ -8595,6 +8588,11 @@ static bool CheckNonTypeTemplatePartialSpecializationArgs(
85958588 continue ;
85968589 }
85978590
8591+ if (isa<RecoveryExpr>(ArgExpr)) {
8592+ HasError = true ;
8593+ continue ;
8594+ }
8595+
85988596 // C++ [temp.class.spec]p9:
85998597 // Within the argument list of a class template partial
86008598 // specialization, the following restrictions apply:
@@ -8638,7 +8636,7 @@ static bool CheckNonTypeTemplatePartialSpecializationArgs(
86388636 }
86398637 }
86408638
8641- return false ;
8639+ return HasError ;
86428640}
86438641
86448642bool Sema::CheckTemplatePartialSpecializationArgs (
0 commit comments