@@ -3553,15 +3553,14 @@ static unsigned getPackIndexForParam(Sema &S,
3553
3553
llvm_unreachable (" parameter index would not be produced from template" );
3554
3554
}
3555
3555
3556
- // if `Specialization` is a `CXXConstructorDecl` or `CXXConversionDecl`
3557
- // we try to instantiate and update its explicit specifier after constraint
3556
+ // if `Specialization` is a `CXXConstructorDecl` or `CXXConversionDecl`,
3557
+ // we'll try to instantiate and update its explicit specifier after constraint
3558
3558
// checking.
3559
- static Sema::TemplateDeductionResult
3560
- resolveExplicitSpecifier (Sema &S, FunctionDecl *Specialization,
3561
- const MultiLevelTemplateArgumentList &SubstArgs,
3562
- TemplateDeductionInfo &Info,
3563
- FunctionTemplateDecl *FunctionTemplate,
3564
- ArrayRef<TemplateArgument> DeducedArgs) {
3559
+ static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred (
3560
+ Sema &S, FunctionDecl *Specialization,
3561
+ const MultiLevelTemplateArgumentList &SubstArgs,
3562
+ TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate,
3563
+ ArrayRef<TemplateArgument> DeducedArgs) {
3565
3564
auto GetExplicitSpecifier = [](FunctionDecl *D) {
3566
3565
return isa<CXXConstructorDecl>(D)
3567
3566
? cast<CXXConstructorDecl>(D)->getExplicitSpecifier ()
@@ -3581,19 +3580,24 @@ resolveExplicitSpecifier(Sema &S, FunctionDecl *Specialization,
3581
3580
if (!Expr->isValueDependent ()) {
3582
3581
return Sema::TDK_Success;
3583
3582
}
3584
- // TemplateDeclInstantiator::InitFunctionInstantiation set the
3585
- // ActiveInstType to TemplateInstantiation, but we need
3586
- // to enable SFINAE when instantiating an explicit specifier.
3583
+ // The `InstantiatingTemplate` here is used to restore `ActiveInstType` to
3584
+ // `DeducedTemplateArgumentSubstitution` because ActiveInstType was set to
3585
+ // `TemplateInstantiation` in
3586
+ // `TemplateDeclInstantiator::InitFunctionInstantiation`. The real depth of
3587
+ // instantiation should be the same as the depth in
3588
+ // `FinishTemplateArgumentDeduction`.
3589
+ // So we don't check `InstantiatingTemplate::IsValid` here.
3587
3590
Sema::InstantiatingTemplate Inst (
3588
3591
S, Info.getLocation (), FunctionTemplate, DeducedArgs,
3589
3592
Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info);
3593
+ Sema::SFINAETrap Trap (S);
3590
3594
const auto Instantiated = S.instantiateExplicitSpecifier (SubstArgs, ES);
3591
- if (Instantiated.isInvalid ()) {
3595
+ if (Instantiated.isInvalid () || Trap. hasErrorOccurred () ) {
3592
3596
Specialization->setInvalidDecl (true );
3593
- return clang:: Sema::TDK_SubstitutionFailure;
3597
+ return Sema::TDK_SubstitutionFailure;
3594
3598
}
3595
3599
SetExplicitSpecifier (Specialization, Instantiated);
3596
- return clang:: Sema::TDK_Success;
3600
+ return Sema::TDK_Success;
3597
3601
}
3598
3602
3599
3603
// / Finish template argument deduction for a function template,
@@ -3725,13 +3729,13 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
3725
3729
}
3726
3730
}
3727
3731
3728
- // We skipped the instantiation of the explicit-specifier during subst the
3729
- // FD before. So we try to instantiate it back if the `Specialization` is a
3730
- // constructor or a conversion.
3732
+ // We skipped the instantiation of the explicit-specifier during the
3733
+ // substitution of `FD` before. So, we try to instantiate it back if
3734
+ // `Specialization` is either a constructor or a conversion function .
3731
3735
if (isa<CXXConstructorDecl, CXXConversionDecl>(Specialization)) {
3732
- if (TDK_Success !=
3733
- resolveExplicitSpecifier ( *this , Specialization, SubstArgs, Info,
3734
- FunctionTemplate, DeducedArgs)) {
3736
+ if (TDK_Success != instantiateExplicitSpecifierDeferred (
3737
+ *this , Specialization, SubstArgs, Info,
3738
+ FunctionTemplate, DeducedArgs)) {
3735
3739
return TDK_SubstitutionFailure;
3736
3740
}
3737
3741
}
0 commit comments