diff options
author | Younan Zhang <zyn7109@gmail.com> | 2024-11-07 15:37:14 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-07 15:37:14 +0800 |
commit | adb0d8ddceb143749c519d14b8b31b481071da77 (patch) | |
tree | 3da82720a5923229fb82b267a0f272d18e1ad3db /clang/lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 9f796159f28775b3f93d77e173c1fd3413c2e60e (diff) | |
download | llvm-adb0d8ddceb143749c519d14b8b31b481071da77.zip llvm-adb0d8ddceb143749c519d14b8b31b481071da77.tar.gz llvm-adb0d8ddceb143749c519d14b8b31b481071da77.tar.bz2 |
[Clang] Distinguish expanding-pack-in-place cases for SubstTemplateTypeParmTypes (#114220)
In 50e5411e4, we preserved the pack substitution index within
SubstTemplateTypeParmType nodes and performed in-place expansions of
packs such that type constraints on a lambda that serve as a pattern of
a fold expression could be evaluated if the type constraints contain any
packs that are expanded by the fold expression.
However, we made an incorrect assumption of the condition under which
in-place expansion should occur. For example, a SizeOfPackExpr case
relies on SubstTemplateTypeParmType nodes being transformed to
SubstTemplateTypeParmPackTypes rather than expanding them immediately in
place.
This fixes that by adding a flag to SubstTemplateTypeParmType to
discriminate such in-place expansion situations.
Fixes https://github.com/llvm/llvm-project/issues/113518
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index b3ae965..b1b92c0 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1661,14 +1661,17 @@ namespace { QualType TransformSubstTemplateTypeParmType(TypeLocBuilder &TLB, SubstTemplateTypeParmTypeLoc TL) { - if (SemaRef.CodeSynthesisContexts.back().Kind != - Sema::CodeSynthesisContext::ConstraintSubstitution) + const SubstTemplateTypeParmType *Type = TL.getTypePtr(); + if (Type->getSubstitutionFlag() != + SubstTemplateTypeParmTypeFlag::ExpandPacksInPlace) return inherited::TransformSubstTemplateTypeParmType(TLB, TL); - auto PackIndex = TL.getTypePtr()->getPackIndex(); - std::optional<Sema::ArgumentPackSubstitutionIndexRAII> SubstIndex; - if (SemaRef.ArgumentPackSubstitutionIndex == -1 && PackIndex) - SubstIndex.emplace(SemaRef, *PackIndex); + assert(Type->getPackIndex()); + TemplateArgument TA = TemplateArgs( + Type->getReplacedParameter()->getDepth(), Type->getIndex()); + assert(*Type->getPackIndex() + 1 <= TA.pack_size()); + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex( + SemaRef, TA.pack_size() - 1 - *Type->getPackIndex()); return inherited::TransformSubstTemplateTypeParmType(TLB, TL); } @@ -3147,7 +3150,11 @@ struct ExpandPackedTypeConstraints using inherited = TreeTransform<ExpandPackedTypeConstraints>; - ExpandPackedTypeConstraints(Sema &SemaRef) : inherited(SemaRef) {} + const MultiLevelTemplateArgumentList &TemplateArgs; + + ExpandPackedTypeConstraints( + Sema &SemaRef, const MultiLevelTemplateArgumentList &TemplateArgs) + : inherited(SemaRef), TemplateArgs(TemplateArgs) {} using inherited::TransformTemplateTypeParmType; @@ -3163,9 +3170,15 @@ struct ExpandPackedTypeConstraints assert(SemaRef.ArgumentPackSubstitutionIndex != -1); + TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex()); + + std::optional<unsigned> PackIndex; + if (Arg.getKind() == TemplateArgument::Pack) + PackIndex = Arg.pack_size() - 1 - SemaRef.ArgumentPackSubstitutionIndex; + QualType Result = SemaRef.Context.getSubstTemplateTypeParmType( - TL.getType(), T->getDecl(), T->getIndex(), - SemaRef.ArgumentPackSubstitutionIndex); + TL.getType(), T->getDecl(), T->getIndex(), PackIndex, + SubstTemplateTypeParmTypeFlag::ExpandPacksInPlace); SubstTemplateTypeParmTypeLoc NewTL = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); @@ -3224,8 +3237,8 @@ bool Sema::SubstTypeConstraint( TemplateArgumentListInfo InstArgs; InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc); InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc); - if (ExpandPackedTypeConstraints(*this).SubstTemplateArguments( - TemplArgInfo->arguments(), InstArgs)) + if (ExpandPackedTypeConstraints(*this, TemplateArgs) + .SubstTemplateArguments(TemplArgInfo->arguments(), InstArgs)) return true; // The type of the original parameter. |