This is an archive of the discontinued LLVM Phabricator instance.

clang: fix early substitution of alias templates
Needs ReviewPublic

Authored by mizvekov on Jun 8 2022, 3:02 PM.

Details

Summary

When substituting alias templates, we stop bumping up template
parameters below current substitution level.

Fixes PR55886.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Diff Detail

Event Timeline

mizvekov created this revision.Jun 8 2022, 3:02 PM
Herald added a project: Restricted Project. · View Herald Transcript
mizvekov published this revision for review.Jun 8 2022, 4:54 PM
mizvekov added a reviewer: rsmith.
Herald added a project: Restricted Project. · View Herald TranscriptJun 8 2022, 4:54 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

@rsmith , I have marked the few spots where the change is meaningful.

clang/include/clang/Sema/Template.h
515–524

mark

652–671

mark

clang/lib/Sema/SemaTemplateInstantiate.cpp
931–941

mark

1195–1210

mark

1864

mark

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
2763

mark

2917–2922

mark

3055–3061

mark

clang/test/AST/ast-dump-template-decls.cpp
124

mark

mizvekov added inline comments.Jun 8 2022, 5:27 PM
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
1031

mark

rsmith added inline comments.Jun 10 2022, 5:27 PM
clang/lib/Sema/SemaTemplateInstantiate.cpp
1864

Instead of adding the new EarlySubstitution flag and wiring it through everywhere, can you use the existing MultiLevelTemplateArgumentList::getNewDepth function? That already handles the case of a depth that's within the number of retained outer levels. We might need to set the number of retained outer levels properly when doing alias template substitution; I'm not sure if we do so currently and I suspect we don't.

mizvekov added inline comments.Jun 10 2022, 6:58 PM
clang/lib/Sema/SemaTemplateInstantiate.cpp
1864

I think we do set the number of outer levels correctly when substituting within the type of alias templates, circa SemaTemplate.cpp:3718:

// Only substitute for the innermost template argument list.
MultiLevelTemplateArgumentList TemplateArgLists;
TemplateArgLists.addOuterTemplateArguments(&StackTemplateArgs);
TemplateArgLists.addOuterRetainedLevels(
    AliasTemplate->getTemplateParameters()->getDepth());

What the flag was done to deal with is what happens in TemplateDeclInstantiator::VisitTypeAliasTemplateDecl, when replacing just the inner level. We need to substitute there without changing any depths, including the template parameters of the alias itself, and I could not find a way to do that without extending it with the new flag.

Anyway, I will think about this again.
I ended up finding another test case which this patch only partially helps, so I have been back investigating this problem again: https://godbolt.org/z/9fGb1KKvq

template <typename... As> struct Y;
template <typename ...Bs> using Z = Y<Bs...>;
template <typename ...Cs> struct foo {
  template <typename ...Ds> using bind = Z<Ds..., Cs...>;
};
using U = foo<int>::bind<char>;
mizvekov added inline comments.Jun 10 2022, 7:22 PM
clang/lib/Sema/SemaTemplateInstantiate.cpp
1864

Though that last test case seems actually to be a wrong index problem, not wrong depth.

mizvekov updated this revision to Diff 436155.Jun 11 2022, 11:43 AM
  • much smaller patch, puts the new flag as a mutable member of MultiLevelTemplateArgumentList
mizvekov added inline comments.Jun 11 2022, 11:46 AM
clang/lib/Sema/SemaTemplateInstantiate.cpp
1864

That last new test case hits an unrelated problem besides this one, so I will deal with it in a separate patch.