aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorYounan Zhang <zyn7109@gmail.com>2025-03-22 22:55:58 +0800
committerGitHub <noreply@github.com>2025-03-22 22:55:58 +0800
commit032ad590d6bac76965fac17b9f2ce41e076a5a0a (patch)
treecbd5a7ee80724e8a583b376f7a201409958c0150 /clang/lib/Sema/SemaTemplateInstantiate.cpp
parent2186199d085b80fe5d254148c0e1f99412da9026 (diff)
downloadllvm-032ad590d6bac76965fac17b9f2ce41e076a5a0a.zip
llvm-032ad590d6bac76965fac17b9f2ce41e076a5a0a.tar.gz
llvm-032ad590d6bac76965fac17b9f2ce41e076a5a0a.tar.bz2
[Clang] Fix various bugs in alias CTAD transform (#132061)
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp46
1 files changed, 34 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index ad49d6f..00dcadb 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1348,6 +1348,16 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
return std::nullopt;
}
+static TemplateArgument
+getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg) {
+ assert(S.ArgumentPackSubstitutionIndex >= 0);
+ assert(S.ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
+ Arg = Arg.pack_begin()[S.ArgumentPackSubstitutionIndex];
+ if (Arg.isPackExpansion())
+ Arg = Arg.getPackExpansionPattern();
+ return Arg;
+}
+
//===----------------------------------------------------------------------===/
// Template Instantiation for Types
//===----------------------------------------------------------------------===/
@@ -1467,11 +1477,13 @@ namespace {
}
}
- static TemplateArgument
+ TemplateArgument
getTemplateArgumentPackPatternForRewrite(const TemplateArgument &TA) {
if (TA.getKind() != TemplateArgument::Pack)
return TA;
- assert(TA.pack_size() == 1 &&
+ if (SemaRef.ArgumentPackSubstitutionIndex != -1)
+ return getPackSubstitutedTemplateArgument(SemaRef, TA);
+ assert(TA.pack_size() == 1 && TA.pack_begin()->isPackExpansion() &&
"unexpected pack arguments in template rewrite");
TemplateArgument Arg = *TA.pack_begin();
if (Arg.isPackExpansion())
@@ -1632,6 +1644,9 @@ namespace {
std::vector<TemplateArgument> TArgs;
switch (Arg.getKind()) {
case TemplateArgument::Pack:
+ assert(SemaRef.CodeSynthesisContexts.empty() ||
+ SemaRef.CodeSynthesisContexts.back().Kind ==
+ Sema::CodeSynthesisContext::BuildingDeductionGuides);
// Literally rewrite the template argument pack, instead of unpacking
// it.
for (auto &pack : Arg.getPackAsArray()) {
@@ -1652,6 +1667,23 @@ namespace {
return inherited::TransformTemplateArgument(Input, Output, Uneval);
}
+ std::optional<unsigned> ComputeSizeOfPackExprWithoutSubstitution(
+ ArrayRef<TemplateArgument> PackArgs) {
+ // Don't do this when rewriting template parameters for CTAD:
+ // 1) The heuristic needs the unpacked Subst* nodes to figure out the
+ // expanded size, but this never applies since Subst* nodes are not
+ // created in rewrite scenarios.
+ //
+ // 2) The heuristic substitutes into the pattern with pack expansion
+ // suppressed, which does not meet the requirements for argument
+ // rewriting when template arguments include a non-pack matching against
+ // a pack, particularly when rewriting an alias CTAD.
+ if (TemplateArgs.isRewrite())
+ return std::nullopt;
+
+ return inherited::ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
+ }
+
template<typename Fn>
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL,
@@ -1871,16 +1903,6 @@ bool TemplateInstantiator::AlreadyTransformed(QualType T) {
return true;
}
-static TemplateArgument
-getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg) {
- assert(S.ArgumentPackSubstitutionIndex >= 0);
- assert(S.ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
- Arg = Arg.pack_begin()[S.ArgumentPackSubstitutionIndex];
- if (Arg.isPackExpansion())
- Arg = Arg.getPackExpansionPattern();
- return Arg;
-}
-
Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
if (!D)
return nullptr;