[clang] 2c2d291 - [concepts] Extract function template pack arguments from the current instantiation if possible (#80594)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 5 17:59:20 PST 2024
Author: Younan Zhang
Date: 2024-02-06T09:59:16+08:00
New Revision: 2c2d291b4568381999442e47fc77f949f19be0bc
URL: https://github.com/llvm/llvm-project/commit/2c2d291b4568381999442e47fc77f949f19be0bc
DIFF: https://github.com/llvm/llvm-project/commit/2c2d291b4568381999442e47fc77f949f19be0bc.diff
LOG: [concepts] Extract function template pack arguments from the current instantiation if possible (#80594)
Before the constraint substitution, we employ
`getTemplateInstantiationArgs`, which in turn attempts to inspect
`TemplateArgument`s from the function template. For parameter packs from
their parent contexts, we used to extract the arguments from the
specialization type, in which could result in non-canonical argument
types e.g. `PackExpansionType`.
This may break the contract that, during a tree transformation, in
`TreeTransform::TryExpandParameterPacks`, the corresponding
`TemplateArgument`s for an `UnexpandedParameterPack` are expected to be
of `Pack` kinds if we're expanding template parameters.
Fixes https://github.com/llvm/llvm-project/issues/72557.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/SemaTemplate/concepts-out-of-line-def.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3596109bf044f..4d57ea4fd55b8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -197,6 +197,9 @@ Bug Fixes to C++ Support
Fixes (`#67976 <https://github.com/llvm/llvm-project/issues/67976>`_)
- Fix crash and diagnostic with const qualified member operator new.
Fixes (`#79748 <https://github.com/llvm/llvm-project/issues/79748>`_)
+- Fixed a crash where substituting into a requires-expression that involves parameter packs
+ during the equivalence determination of two constraint expressions.
+ (`#72557 <https://github.com/llvm/llvm-project/issues/72557>`_)
- Fix a crash when specializing an out-of-line member function with a default
parameter where we did an incorrect specialization of the initialization of
the default parameter.
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index e5999fa50117e..6d59180bc446d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -241,10 +241,38 @@ Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
while (const Type *Ty = NNS ? NNS->getAsType() : nullptr) {
if (NNS->isInstantiationDependent()) {
- if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>())
+ if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
+ ArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
+ // Prefer template arguments from the injected-class-type if possible.
+ // For example,
+ // ```cpp
+ // template <class... Pack> struct S {
+ // template <class T> void foo();
+ // };
+ // template <class... Pack> template <class T>
+ // ^^^^^^^^^^^^^ InjectedTemplateArgs
+ // They're of kind TemplateArgument::Pack, not of
+ // TemplateArgument::Type.
+ // void S<Pack...>::foo() {}
+ // ^^^^^^^
+ // TSTy->template_arguments() (which are of PackExpansionType)
+ // ```
+ // This meets the contract in
+ // TreeTransform::TryExpandParameterPacks that the template arguments
+ // for unexpanded parameters should be of a Pack kind.
+ if (TSTy->isCurrentInstantiation()) {
+ auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();
+ if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
+ Arguments = CTD->getInjectedTemplateArgs();
+ else if (auto *Specialization =
+ dyn_cast<ClassTemplateSpecializationDecl>(RD))
+ Arguments =
+ Specialization->getTemplateInstantiationArgs().asArray();
+ }
Result.addOuterTemplateArguments(
- const_cast<FunctionTemplateDecl *>(FTD), TSTy->template_arguments(),
+ const_cast<FunctionTemplateDecl *>(FTD), Arguments,
/*Final=*/false);
+ }
}
NNS = NNS->getPrefix();
diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index b6fea2e0b4b31..0142efcdc3ee8 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -581,3 +581,21 @@ void S<T>::test(T target, U... value)
}
{}
} // namespace GH74447
+
+namespace GH72557 {
+
+template <typename...>
+concept IsAnyOf = true;
+
+template <class... DerTs> struct DerivedCollection {
+ template <class DerT>
+ requires IsAnyOf<DerTs...>
+ unsigned long index();
+};
+
+template <class... DerTs>
+template <class DerT>
+ requires IsAnyOf<DerTs...>
+unsigned long DerivedCollection<DerTs...>::index() {}
+
+} // namespace GH72557
More information about the cfe-commits
mailing list