[clang] [Clang] Handle default template arguments for alias CTAD guides (PR #134807)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 13 23:50:32 PDT 2025
================
@@ -690,6 +690,23 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
SemaRef.MarkUsedTemplateParameters(
DeducedArgs, TemplateParamsList->getDepth(), ReferencedTemplateParams);
+ auto MarkDefaultArgs = [&](auto *Param) {
+ if (!Param || !Param->hasDefaultArgument())
+ return;
+ SemaRef.MarkUsedTemplateParameters(
+ Param->getDefaultArgument().getArgument(),
+ TemplateParamsList->getDepth(), ReferencedTemplateParams);
+ };
+
+ for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
+ if (!ReferencedTemplateParams[Index])
+ continue;
+ auto *Param = TemplateParamsList->getParam(Index);
+ MarkDefaultArgs(dyn_cast<TemplateTypeParmDecl>(Param));
+ MarkDefaultArgs(dyn_cast<NonTypeTemplateParmDecl>(Param));
+ MarkDefaultArgs(dyn_cast<TemplateTemplateParmDecl>(Param));
+ }
+
----------------
zyn0217 wrote:
@mizvekov I looked into `ConvertDeducedTemplateArguments` and I'm afraid it won't help
In deduction guide synthesizing, we have a unique template parameter transform that does handle default parameters (which also covers non-alias deduction guide synthesizing) so when we find a parameter (e.g. `U` in example) used by the RHS (`A<U>`), we form a new TTP on top of the TTP `U = T`. And, as `T` is not referenced by `A<U>`, the declaration of which won't be created anyway, so we ended up with a problematic `template <class U = <template-param-0-0>>` in the eventual CTAD guide.
```cpp
template <class _Ty> struct A {};
template <class T = int, class U = T>
using AA = A<U>;
```
This is where the problem lies. And with `ConvertDeducedTemplateArguments`, which would substitute the default arguments with the deduced ones in non-rewrite mode, we end up building Subst* nodes that we never want in CTAD.
https://github.com/llvm/llvm-project/pull/134807
More information about the cfe-commits
mailing list