Author: Younan Zhang Date: 2025-10-20T18:32:14+08:00 New Revision: 136c40667ebc43ffc13b32cb2227dd69a7d85b81
URL: https://github.com/llvm/llvm-project/commit/136c40667ebc43ffc13b32cb2227dd69a7d85b81 DIFF: https://github.com/llvm/llvm-project/commit/136c40667ebc43ffc13b32cb2227dd69a7d85b81.diff LOG: [Clang] Give empty template parameter mapping an empty MLTAL (#164051) There are cases where atomic constraints are independent of template parameters, yet we still have a template parameter mapping. We don't bother translating template arguments for them. Note that we retain an empty parameter mapping rather than none at all, as the former may improve cache hit rates (We don't profile MLTAL but profile the empty template argument list instead.) This is a regression on trunk, so there's no release note. Added: Modified: clang/lib/Sema/SemaConcept.cpp clang/test/SemaTemplate/concepts.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 829bd87599ac9..f77fca2a69e00 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -570,6 +570,11 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments( if (!Constraint.hasParameterMapping()) return std::move(MLTAL); + // The mapping is empty, meaning no template arguments are needed for + // evaluation. + if (Constraint.getParameterMapping().empty()) + return MultiLevelTemplateArgumentList(); + TemplateDeductionInfo Info(Constraint.getBeginLoc()); Sema::InstantiatingTemplate Inst( S, Constraint.getBeginLoc(), @@ -2017,8 +2022,13 @@ void SubstituteParameterMappings::buildParameterMapping( SemaRef.MarkUsedTemplateParameters(Args->arguments(), /*Depth=*/0, OccurringIndices); } + unsigned Size = OccurringIndices.count(); + // When the constraint is independent of any template parameters, + // we build an empty mapping so that we can distinguish these cases + // from cases where no mapping exists at all, e.g. when there are only atomic + // constraints. TemplateArgumentLoc *TempArgs = - new (SemaRef.Context) TemplateArgumentLoc[OccurringIndices.count()]; + new (SemaRef.Context) TemplateArgumentLoc[Size]; llvm::SmallVector<NamedDecl *> UsedParams; for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I) { SourceLocation Loc = ArgsAsWritten->NumTemplateArgs > I @@ -2039,7 +2049,6 @@ void SubstituteParameterMappings::buildParameterMapping( TemplateParams->getLAngleLoc(), UsedParams, /*RAngleLoc=*/SourceLocation(), /*RequiresClause=*/nullptr); - unsigned Size = OccurringIndices.count(); N.updateParameterMapping( std::move(OccurringIndices), std::move(OccurringIndicesForSubsumption), MutableArrayRef<TemplateArgumentLoc>{TempArgs, Size}, UsedList); @@ -2050,6 +2059,10 @@ bool SubstituteParameterMappings::substitute( if (!N.hasParameterMapping()) buildParameterMapping(N); + // If the parameter mapping is empty, there is nothing to substitute. + if (N.getParameterMapping().empty()) + return false; + SourceLocation InstLocBegin, InstLocEnd; llvm::ArrayRef Arguments = ArgsAsWritten->arguments(); if (Arguments.empty()) { diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index a54bc02226058..5b0f3d39d9648 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -1441,6 +1441,24 @@ void main() { Feeder<int>{}.feed<Cat<int>>(); } } +namespace case9 { + +template <typename> +concept a = requires { requires true; }; +template <typename T> +concept b = a<typename T::EntitySpec>; +template <typename T> +concept c = requires { b<T>; }; +template <typename T> + requires c<T> +struct s; +template <typename> constexpr bool f() { return true; } +template <typename T> constexpr bool d = f<T>(); +struct s2; +static_assert(d<s<s2>>); + +} + } namespace GH162125 { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
