https://github.com/LYP951018 updated https://github.com/llvm/llvm-project/pull/70548
From 11ceaed39b3f0c60c5a44c3b3a2b5856e7ee9a8d Mon Sep 17 00:00:00 2001 From: letrec <liuyupei951...@hotmail.com> Date: Sat, 28 Oct 2023 18:05:36 +0800 Subject: [PATCH 1/7] Defer the instantiation of explicit-specifier after constraint checking --- clang/docs/ReleaseNotes.rst | 4 ++ clang/include/clang/Sema/Sema.h | 3 + clang/lib/Sema/SemaTemplateDeduction.cpp | 59 +++++++++++++++++++ .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 40 ++++++++----- .../SemaCXX/cxx2a-explicit-bool-deferred.cpp | 31 ++++++++++ 5 files changed, 123 insertions(+), 14 deletions(-) create mode 100644 clang/test/SemaCXX/cxx2a-explicit-bool-deferred.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index bc28bb567f6932a..d9980694de40f6f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -670,6 +670,10 @@ Bug Fixes to C++ Support default initializing a base class in a constant expression context. Fixes: (`#69890 <https://github.com/llvm/llvm-project/issues/69890>`_) +- Clang now defers the instantiation of explicit specifier until constraint checking + completes (except deduction guides). Fixes: + (`#59827 <https://github.com/llvm/llvm-project/issues/59827>`_) + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 91a4211a5cf5cce..daed24be0a86d11 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10430,6 +10430,9 @@ class Sema final { const CXXConstructorDecl *Tmpl, const MultiLevelTemplateArgumentList &TemplateArgs); + ExplicitSpecifier instantiateExplicitSpecifier( + const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES); + NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext = false); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 0b3f0247ea3bee3..f06332770f51d1f 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3553,6 +3553,56 @@ static unsigned getPackIndexForParam(Sema &S, llvm_unreachable("parameter index would not be produced from template"); } +// if `Specialization` is a `CXXConstructorDecl` or `CXXConversionDecl` +// we try to instantiate and update its explicit specifier after constraint +// checking. +static Sema::TemplateDeductionResult +tryInstantiateExplicitSpecifier(Sema &S, FunctionDecl *Specialization, + const MultiLevelTemplateArgumentList &SubstArgs, + TemplateDeductionInfo &Info, + FunctionTemplateDecl *FunctionTemplate, + ArrayRef<TemplateArgument> DeducedArgs) { + + const auto TryInstantiateExplicitSpecifierForSingleDecl = + [&](auto *ExplicitDecl) { + ExplicitSpecifier ExplicitSpecifier = + ExplicitDecl->getExplicitSpecifier(); + Expr *const Expr = ExplicitSpecifier.getExpr(); + if (!Expr) { + return Sema::TDK_Success; + } + if (!Expr->isValueDependent()) { + return Sema::TDK_Success; + } + // TemplateDeclInstantiator::InitFunctionInstantiation set the + // ActiveInstType to TemplateInstantiation, but we need + // to enable SFINAE when instantiating explicit specifier. + Sema::InstantiatingTemplate Inst( + S, Info.getLocation(), FunctionTemplate, DeducedArgs, + Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, + Info); + const auto Instantiated = + S.instantiateExplicitSpecifier(SubstArgs, ExplicitSpecifier); + if (Instantiated.isInvalid()) { + ExplicitDecl->setInvalidDecl(true); + return clang::Sema::TDK_SubstitutionFailure; + } + ExplicitDecl->setExplicitSpecifier(Instantiated); + return clang::Sema::TDK_Success; + }; + Sema::TemplateDeductionResult DeductionResult = clang::Sema::TDK_Success; + if (CXXConstructorDecl *ConstructorDecl = + dyn_cast_or_null<CXXConstructorDecl>(Specialization)) { + DeductionResult = + TryInstantiateExplicitSpecifierForSingleDecl(ConstructorDecl); + } else if (CXXConversionDecl *ConversionDecl = + dyn_cast_or_null<CXXConversionDecl>(Specialization)) { + DeductionResult = + TryInstantiateExplicitSpecifierForSingleDecl(ConversionDecl); + } + return DeductionResult; +} + /// Finish template argument deduction for a function template, /// checking the deduced template arguments for completeness and forming /// the function template specialization. @@ -3682,6 +3732,15 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( } } + // We skipped the instantiation of the explicit-specifier during subst the + // decl before. Now, we try to instantiate it back if the Specialization is a + // constructor or a conversion. + if (TDK_Success != + tryInstantiateExplicitSpecifier(*this, Specialization, SubstArgs, Info, + FunctionTemplate, DeducedArgs)) { + return TDK_SubstitutionFailure; + } + if (OriginalCallArgs) { // C++ [temp.deduct.call]p4: // In general, the deduction process attempts to find template argument diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 78a7892a35a320b..163dbef03e80a4d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -563,18 +563,16 @@ static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr( S.addAMDGPUFlatWorkGroupSizeAttr(New, Attr, MinExpr, MaxExpr); } -static ExplicitSpecifier -instantiateExplicitSpecifier(Sema &S, - const MultiLevelTemplateArgumentList &TemplateArgs, - ExplicitSpecifier ES, FunctionDecl *New) { +ExplicitSpecifier Sema::instantiateExplicitSpecifier( + const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES) { if (!ES.getExpr()) return ES; Expr *OldCond = ES.getExpr(); Expr *Cond = nullptr; { EnterExpressionEvaluationContext Unevaluated( - S, Sema::ExpressionEvaluationContext::ConstantEvaluated); - ExprResult SubstResult = S.SubstExpr(OldCond, TemplateArgs); + *this, Sema::ExpressionEvaluationContext::ConstantEvaluated); + ExprResult SubstResult = SubstExpr(OldCond, TemplateArgs); if (SubstResult.isInvalid()) { return ExplicitSpecifier::Invalid(); } @@ -582,7 +580,7 @@ instantiateExplicitSpecifier(Sema &S, } ExplicitSpecifier Result(Cond, ES.getKind()); if (!Cond->isTypeDependent()) - S.tryResolveExplicitSpecifier(Result); + tryResolveExplicitSpecifier(Result); return Result; } @@ -2073,8 +2071,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( ExplicitSpecifier InstantiatedExplicitSpecifier; if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) { - InstantiatedExplicitSpecifier = instantiateExplicitSpecifier( - SemaRef, TemplateArgs, DGuide->getExplicitSpecifier(), DGuide); + InstantiatedExplicitSpecifier = SemaRef.instantiateExplicitSpecifier( + TemplateArgs, DGuide->getExplicitSpecifier()); if (InstantiatedExplicitSpecifier.isInvalid()) return nullptr; } @@ -2453,11 +2451,25 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( } } - ExplicitSpecifier InstantiatedExplicitSpecifier = - instantiateExplicitSpecifier(SemaRef, TemplateArgs, - ExplicitSpecifier::getFromDecl(D), D); - if (InstantiatedExplicitSpecifier.isInvalid()) - return nullptr; + auto InstantiatedExplicitSpecifier = ExplicitSpecifier::getFromDecl(D); + // deduction guides need this + const bool CouldInstantiate = + InstantiatedExplicitSpecifier.getExpr() == nullptr || + !InstantiatedExplicitSpecifier.getExpr()->isValueDependent(); + + // Delay the instantiation of the explicit-specifier until after the + // constraints are checked during template argument deduction. + if (CouldInstantiate || + SemaRef.CodeSynthesisContexts.back().Kind != + Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution) { + InstantiatedExplicitSpecifier = SemaRef.instantiateExplicitSpecifier( + TemplateArgs, InstantiatedExplicitSpecifier); + + if (InstantiatedExplicitSpecifier.isInvalid()) + return nullptr; + } else { + InstantiatedExplicitSpecifier.setKind(ExplicitSpecKind::Unresolved); + } // Implicit destructors/constructors created for local classes in // DeclareImplicit* (see SemaDeclCXX.cpp) might not have an associated TSI. diff --git a/clang/test/SemaCXX/cxx2a-explicit-bool-deferred.cpp b/clang/test/SemaCXX/cxx2a-explicit-bool-deferred.cpp new file mode 100644 index 000000000000000..4d667008f2e2763 --- /dev/null +++ b/clang/test/SemaCXX/cxx2a-explicit-bool-deferred.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s + +template <typename T1, typename T2> struct is_same { + static constexpr bool value = false; +}; + +template <typename T> struct is_same<T, T> { + static constexpr bool value = true; +}; + +template <class T, class U> +concept SameHelper = is_same<T, U>::value; +template <class T, class U> +concept same_as = SameHelper<T, U> && SameHelper<U, T>; + +namespace deferred_instantiation { +template <class X> constexpr X do_not_instantiate() { return nullptr; } + +struct T { + template <same_as<float> X> explicit(do_not_instantiate<X>()) T(X) {} + + T(int) {} +}; + +T t(5); +// expected-error@17{{cannot initialize}} +// expected-note@20{{in instantiation of function template specialization}} +// expected-note@30{{while substituting deduced template arguments}} +// expected-note@30{{in instantiation of function template specialization}} +T t2(5.0f); +} // namespace deferred_instantiation From d7db83b18369d3b6bfa485befde699b01148dd8f Mon Sep 17 00:00:00 2001 From: letrec <liuyupei951...@hotmail.com> Date: Tue, 31 Oct 2023 00:47:39 +0800 Subject: [PATCH 2/7] fix CR comments --- clang/lib/Sema/SemaTemplateDeduction.cpp | 94 ++++++++++++------------ 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index f06332770f51d1f..0218c4319ad01a0 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3557,50 +3557,44 @@ static unsigned getPackIndexForParam(Sema &S, // we try to instantiate and update its explicit specifier after constraint // checking. static Sema::TemplateDeductionResult -tryInstantiateExplicitSpecifier(Sema &S, FunctionDecl *Specialization, - const MultiLevelTemplateArgumentList &SubstArgs, - TemplateDeductionInfo &Info, - FunctionTemplateDecl *FunctionTemplate, - ArrayRef<TemplateArgument> DeducedArgs) { - - const auto TryInstantiateExplicitSpecifierForSingleDecl = - [&](auto *ExplicitDecl) { - ExplicitSpecifier ExplicitSpecifier = - ExplicitDecl->getExplicitSpecifier(); - Expr *const Expr = ExplicitSpecifier.getExpr(); - if (!Expr) { - return Sema::TDK_Success; - } - if (!Expr->isValueDependent()) { - return Sema::TDK_Success; - } - // TemplateDeclInstantiator::InitFunctionInstantiation set the - // ActiveInstType to TemplateInstantiation, but we need - // to enable SFINAE when instantiating explicit specifier. - Sema::InstantiatingTemplate Inst( - S, Info.getLocation(), FunctionTemplate, DeducedArgs, - Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, - Info); - const auto Instantiated = - S.instantiateExplicitSpecifier(SubstArgs, ExplicitSpecifier); - if (Instantiated.isInvalid()) { - ExplicitDecl->setInvalidDecl(true); - return clang::Sema::TDK_SubstitutionFailure; - } - ExplicitDecl->setExplicitSpecifier(Instantiated); - return clang::Sema::TDK_Success; - }; - Sema::TemplateDeductionResult DeductionResult = clang::Sema::TDK_Success; - if (CXXConstructorDecl *ConstructorDecl = - dyn_cast_or_null<CXXConstructorDecl>(Specialization)) { - DeductionResult = - TryInstantiateExplicitSpecifierForSingleDecl(ConstructorDecl); - } else if (CXXConversionDecl *ConversionDecl = - dyn_cast_or_null<CXXConversionDecl>(Specialization)) { - DeductionResult = - TryInstantiateExplicitSpecifierForSingleDecl(ConversionDecl); - } - return DeductionResult; +resolveExplicitSpecifier(Sema &S, FunctionDecl *Specialization, + const MultiLevelTemplateArgumentList &SubstArgs, + TemplateDeductionInfo &Info, + FunctionTemplateDecl *FunctionTemplate, + ArrayRef<TemplateArgument> DeducedArgs) { + auto GetExplicitSpecifier = [](FunctionDecl *D) { + return isa<CXXConstructorDecl>(D) + ? cast<CXXConstructorDecl>(D)->getExplicitSpecifier() + : cast<CXXConversionDecl>(D)->getExplicitSpecifier(); + }; + auto SetExplicitSpecifier = [](FunctionDecl *D, ExplicitSpecifier ES) { + isa<CXXConstructorDecl>(D) + ? cast<CXXConstructorDecl>(D)->setExplicitSpecifier(ES) + : cast<CXXConversionDecl>(D)->setExplicitSpecifier(ES); + }; + + ExplicitSpecifier ExplicitSpecifier = GetExplicitSpecifier(Specialization); + Expr *const Expr = ExplicitSpecifier.getExpr(); + if (!Expr) { + return Sema::TDK_Success; + } + if (!Expr->isValueDependent()) { + return Sema::TDK_Success; + } + // TemplateDeclInstantiator::InitFunctionInstantiation set the + // ActiveInstType to TemplateInstantiation, but we need + // to enable SFINAE when instantiating an explicit specifier. + Sema::InstantiatingTemplate Inst( + S, Info.getLocation(), FunctionTemplate, DeducedArgs, + Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); + const auto Instantiated = + S.instantiateExplicitSpecifier(SubstArgs, ExplicitSpecifier); + if (Instantiated.isInvalid()) { + Specialization->setInvalidDecl(true); + return clang::Sema::TDK_SubstitutionFailure; + } + SetExplicitSpecifier(Specialization, Instantiated); + return clang::Sema::TDK_Success; } /// Finish template argument deduction for a function template, @@ -3733,12 +3727,14 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( } // We skipped the instantiation of the explicit-specifier during subst the - // decl before. Now, we try to instantiate it back if the Specialization is a + // FD before. So we try to instantiate it back if the `Specialization` is a // constructor or a conversion. - if (TDK_Success != - tryInstantiateExplicitSpecifier(*this, Specialization, SubstArgs, Info, - FunctionTemplate, DeducedArgs)) { - return TDK_SubstitutionFailure; + if (isa<CXXConstructorDecl, CXXConversionDecl>(Specialization)) { + if (TDK_Success != + resolveExplicitSpecifier(*this, Specialization, SubstArgs, Info, + FunctionTemplate, DeducedArgs)) { + return TDK_SubstitutionFailure; + } } if (OriginalCallArgs) { From 808802b1e40e9add618072fcfe8b7491a7f17201 Mon Sep 17 00:00:00 2001 From: letrec <liuyupei951...@hotmail.com> Date: Tue, 31 Oct 2023 01:05:57 +0800 Subject: [PATCH 3/7] unify ES identifier --- clang/lib/Sema/SemaTemplateDeduction.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 0218c4319ad01a0..f905391279c02dc 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3573,8 +3573,8 @@ resolveExplicitSpecifier(Sema &S, FunctionDecl *Specialization, : cast<CXXConversionDecl>(D)->setExplicitSpecifier(ES); }; - ExplicitSpecifier ExplicitSpecifier = GetExplicitSpecifier(Specialization); - Expr *const Expr = ExplicitSpecifier.getExpr(); + ExplicitSpecifier ES = GetExplicitSpecifier(Specialization); + Expr *const Expr = ES.getExpr(); if (!Expr) { return Sema::TDK_Success; } @@ -3587,8 +3587,7 @@ resolveExplicitSpecifier(Sema &S, FunctionDecl *Specialization, Sema::InstantiatingTemplate Inst( S, Info.getLocation(), FunctionTemplate, DeducedArgs, Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); - const auto Instantiated = - S.instantiateExplicitSpecifier(SubstArgs, ExplicitSpecifier); + const auto Instantiated = S.instantiateExplicitSpecifier(SubstArgs, ES); if (Instantiated.isInvalid()) { Specialization->setInvalidDecl(true); return clang::Sema::TDK_SubstitutionFailure; From 53c6c6a398ef3b791fa30f7fd3ee011a504dbe0d Mon Sep 17 00:00:00 2001 From: letrec <liuyupei951...@hotmail.com> Date: Tue, 31 Oct 2023 23:56:34 +0800 Subject: [PATCH 4/7] add hasErrorOccurred check --- clang/lib/Sema/SemaTemplateDeduction.cpp | 44 +++++++++++++----------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index f905391279c02dc..c2bfa58b2288241 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3553,15 +3553,14 @@ static unsigned getPackIndexForParam(Sema &S, llvm_unreachable("parameter index would not be produced from template"); } -// if `Specialization` is a `CXXConstructorDecl` or `CXXConversionDecl` -// we try to instantiate and update its explicit specifier after constraint +// if `Specialization` is a `CXXConstructorDecl` or `CXXConversionDecl`, +// we'll try to instantiate and update its explicit specifier after constraint // checking. -static Sema::TemplateDeductionResult -resolveExplicitSpecifier(Sema &S, FunctionDecl *Specialization, - const MultiLevelTemplateArgumentList &SubstArgs, - TemplateDeductionInfo &Info, - FunctionTemplateDecl *FunctionTemplate, - ArrayRef<TemplateArgument> DeducedArgs) { +static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred( + Sema &S, FunctionDecl *Specialization, + const MultiLevelTemplateArgumentList &SubstArgs, + TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate, + ArrayRef<TemplateArgument> DeducedArgs) { auto GetExplicitSpecifier = [](FunctionDecl *D) { return isa<CXXConstructorDecl>(D) ? cast<CXXConstructorDecl>(D)->getExplicitSpecifier() @@ -3581,19 +3580,24 @@ resolveExplicitSpecifier(Sema &S, FunctionDecl *Specialization, if (!Expr->isValueDependent()) { return Sema::TDK_Success; } - // TemplateDeclInstantiator::InitFunctionInstantiation set the - // ActiveInstType to TemplateInstantiation, but we need - // to enable SFINAE when instantiating an explicit specifier. + // The `InstantiatingTemplate` here is used to restore `ActiveInstType` to + // `DeducedTemplateArgumentSubstitution` because ActiveInstType was set to + // `TemplateInstantiation` in + // `TemplateDeclInstantiator::InitFunctionInstantiation`. The real depth of + // instantiation should be the same as the depth in + // `FinishTemplateArgumentDeduction`. + // So we don't check `InstantiatingTemplate::IsValid` here. Sema::InstantiatingTemplate Inst( S, Info.getLocation(), FunctionTemplate, DeducedArgs, Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); + Sema::SFINAETrap Trap(S); const auto Instantiated = S.instantiateExplicitSpecifier(SubstArgs, ES); - if (Instantiated.isInvalid()) { + if (Instantiated.isInvalid() || Trap.hasErrorOccurred()) { Specialization->setInvalidDecl(true); - return clang::Sema::TDK_SubstitutionFailure; + return Sema::TDK_SubstitutionFailure; } SetExplicitSpecifier(Specialization, Instantiated); - return clang::Sema::TDK_Success; + return Sema::TDK_Success; } /// Finish template argument deduction for a function template, @@ -3725,13 +3729,13 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( } } - // We skipped the instantiation of the explicit-specifier during subst the - // FD before. So we try to instantiate it back if the `Specialization` is a - // constructor or a conversion. + // We skipped the instantiation of the explicit-specifier during the + // substitution of `FD` before. So, we try to instantiate it back if + // `Specialization` is either a constructor or a conversion function. if (isa<CXXConstructorDecl, CXXConversionDecl>(Specialization)) { - if (TDK_Success != - resolveExplicitSpecifier(*this, Specialization, SubstArgs, Info, - FunctionTemplate, DeducedArgs)) { + if (TDK_Success != instantiateExplicitSpecifierDeferred( + *this, Specialization, SubstArgs, Info, + FunctionTemplate, DeducedArgs)) { return TDK_SubstitutionFailure; } } From fd03551f26e37ba21d0f5a80ccc581bfbdf40637 Mon Sep 17 00:00:00 2001 From: letrec <liuyupei951...@hotmail.com> Date: Wed, 1 Nov 2023 00:52:12 +0800 Subject: [PATCH 5/7] add `IsInvalid` check --- clang/lib/Sema/SemaTemplateDeduction.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index c2bfa58b2288241..e20ce8f884a9206 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3580,16 +3580,12 @@ static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred( if (!Expr->isValueDependent()) { return Sema::TDK_Success; } - // The `InstantiatingTemplate` here is used to restore `ActiveInstType` to - // `DeducedTemplateArgumentSubstitution` because ActiveInstType was set to - // `TemplateInstantiation` in - // `TemplateDeclInstantiator::InitFunctionInstantiation`. The real depth of - // instantiation should be the same as the depth in - // `FinishTemplateArgumentDeduction`. - // So we don't check `InstantiatingTemplate::IsValid` here. Sema::InstantiatingTemplate Inst( S, Info.getLocation(), FunctionTemplate, DeducedArgs, Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); + if (Inst.isInvalid()) { + return Sema::TDK_InstantiationDepth; + } Sema::SFINAETrap Trap(S); const auto Instantiated = S.instantiateExplicitSpecifier(SubstArgs, ES); if (Instantiated.isInvalid() || Trap.hasErrorOccurred()) { From fe4d5f1f0131baef5a960294d3eea16a3c5d5479 Mon Sep 17 00:00:00 2001 From: letrec <liuyupei951...@hotmail.com> Date: Wed, 1 Nov 2023 00:57:30 +0800 Subject: [PATCH 6/7] remove braces for simple if --- clang/lib/Sema/SemaTemplateDeduction.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e20ce8f884a9206..98d6484515168b9 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3574,18 +3574,16 @@ static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred( ExplicitSpecifier ES = GetExplicitSpecifier(Specialization); Expr *const Expr = ES.getExpr(); - if (!Expr) { + if (!Expr) return Sema::TDK_Success; - } - if (!Expr->isValueDependent()) { + if (!Expr->isValueDependent()) return Sema::TDK_Success; - } + Sema::InstantiatingTemplate Inst( S, Info.getLocation(), FunctionTemplate, DeducedArgs, Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); - if (Inst.isInvalid()) { + if (Inst.isInvalid()) return Sema::TDK_InstantiationDepth; - } Sema::SFINAETrap Trap(S); const auto Instantiated = S.instantiateExplicitSpecifier(SubstArgs, ES); if (Instantiated.isInvalid() || Trap.hasErrorOccurred()) { From aaa687ee2c1246d4800c7d2f4bf1054aaabdee08 Mon Sep 17 00:00:00 2001 From: letrec <liuyupei951...@hotmail.com> Date: Wed, 1 Nov 2023 01:10:30 +0800 Subject: [PATCH 7/7] fix CR comments --- clang/lib/Sema/SemaTemplateDeduction.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 98d6484515168b9..699e0985e595b65 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3573,10 +3573,10 @@ static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred( }; ExplicitSpecifier ES = GetExplicitSpecifier(Specialization); - Expr *const Expr = ES.getExpr(); - if (!Expr) + Expr *ExplicitExpr = ES.getExpr(); + if (!ExplicitExpr) return Sema::TDK_Success; - if (!Expr->isValueDependent()) + if (!ExplicitExpr->isValueDependent()) return Sema::TDK_Success; Sema::InstantiatingTemplate Inst( @@ -3585,12 +3585,13 @@ static Sema::TemplateDeductionResult instantiateExplicitSpecifierDeferred( if (Inst.isInvalid()) return Sema::TDK_InstantiationDepth; Sema::SFINAETrap Trap(S); - const auto Instantiated = S.instantiateExplicitSpecifier(SubstArgs, ES); - if (Instantiated.isInvalid() || Trap.hasErrorOccurred()) { + const ExplicitSpecifier InstantiatedES = + S.instantiateExplicitSpecifier(SubstArgs, ES); + if (InstantiatedES.isInvalid() || Trap.hasErrorOccurred()) { Specialization->setInvalidDecl(true); return Sema::TDK_SubstitutionFailure; } - SetExplicitSpecifier(Specialization, Instantiated); + SetExplicitSpecifier(Specialization, InstantiatedES); return Sema::TDK_Success; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits