Skip to content

Commit d93117d

Browse files
committed
[Clang] Handle default template arguments for alias CTAD guides
It's possible that some deduced template arguments come from default arguments, not just from the return type. So we need to recursively visit the default arguments if the parameter is referenced, thereby the template parameter referenced by the defualt arguments could come along to the synthesized deduction guide.
1 parent 475cbf0 commit d93117d

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

Diff for: clang/docs/ReleaseNotes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ Bug Fixes to C++ Support
384384
- Clang no longer crashes when trying to unify the types of arrays with
385385
certain differences in qualifiers (this could happen during template argument
386386
deduction or when building a ternary operator). (#GH97005)
387+
- Fixed type alias CTAD issues involving default template arguments. (#GH133132)
387388
- The initialization kind of elements of structured bindings
388389
direct-list-initialized from an array is corrected to direct-initialization.
389390
- Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327)

Diff for: clang/lib/Sema/SemaTemplateDeductionGuide.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,23 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
690690
SemaRef.MarkUsedTemplateParameters(
691691
DeducedArgs, TemplateParamsList->getDepth(), ReferencedTemplateParams);
692692

693+
auto MarkDefaultArgs = [&](auto *Param) {
694+
if (!Param || !Param->hasDefaultArgument())
695+
return;
696+
SemaRef.MarkUsedTemplateParameters(
697+
Param->getDefaultArgument().getArgument(),
698+
TemplateParamsList->getDepth(), ReferencedTemplateParams);
699+
};
700+
701+
for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
702+
if (!ReferencedTemplateParams[Index])
703+
continue;
704+
auto *Param = TemplateParamsList->getParam(Index);
705+
MarkDefaultArgs(dyn_cast<TemplateTypeParmDecl>(Param));
706+
MarkDefaultArgs(dyn_cast<NonTypeTemplateParmDecl>(Param));
707+
MarkDefaultArgs(dyn_cast<TemplateTemplateParmDecl>(Param));
708+
}
709+
693710
SmallVector<unsigned> Results;
694711
for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
695712
if (ReferencedTemplateParams[Index])

Diff for: clang/test/SemaTemplate/deduction-guide.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -771,3 +771,42 @@ D d(24);
771771
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U'
772772

773773
} // namespace GH132616_DeductionGuide
774+
775+
namespace GH133132 {
776+
777+
template <class _Ty>
778+
struct A {};
779+
780+
template <class T = int, class U = T>
781+
using AA = A<U>;
782+
783+
AA a{};
784+
785+
// CHECK-LABEL: Dumping GH133132::<deduction guide for AA>:
786+
// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for AA>
787+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 0 T
788+
// CHECK-NEXT: | `-TemplateArgument type 'int'
789+
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
790+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
791+
// CHECK-NEXT: | `-TemplateArgument type 'T':'type-parameter-0-0'
792+
// CHECK-NEXT: | `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0
793+
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'T'
794+
// CHECK-NEXT: |-TypeTraitExpr {{.+}} 'bool' __is_deducible
795+
// CHECK-NEXT: | |-DeducedTemplateSpecializationType {{.+}} 'GH133132::AA' dependent
796+
// CHECK-NEXT: | | `-name: 'GH133132::AA'
797+
// CHECK-NEXT: | | `-TypeAliasTemplateDecl {{.+}} AA
798+
// CHECK-NEXT: | `-TemplateSpecializationType {{.+}} 'A<U>' dependent
799+
// CHECK-NEXT: | |-name: 'A':'GH133132::A' qualified
800+
// CHECK-NEXT: | | `-ClassTemplateDecl {{.+}} A
801+
// CHECK-NEXT: | `-TemplateArgument type 'U':'type-parameter-0-1'
802+
// CHECK-NEXT: | `-SubstTemplateTypeParmType {{.+}} 'U' sugar dependent class depth 0 index 0 _Ty
803+
// CHECK-NEXT: | |-FunctionTemplate {{.+}} '<deduction guide for A>'
804+
// CHECK-NEXT: | `-TemplateTypeParmType {{.+}} 'U' dependent depth 0 index 1
805+
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'U'
806+
// CHECK-NEXT: |-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for AA> 'auto () -> A<U>'
807+
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit used <deduction guide for AA> 'auto () -> A<int>' implicit_instantiation
808+
// CHECK-NEXT: |-TemplateArgument type 'int'
809+
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
810+
// CHECK-NEXT: `-TemplateArgument type 'int'
811+
// CHECK-NEXT: `-BuiltinType {{.+}} 'int'
812+
}

0 commit comments

Comments
 (0)