https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/132669
>From 2894090c356438867c182fd76c9b89354c0bafee Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Mon, 24 Mar 2025 12:43:17 +0800 Subject: [PATCH 1/2] [Clang] Fix the assertion condition after b8d1f3d6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to the example provided by @MagentaTreehouse, I realized the assertion I added didn't cover all valid cases like, when inheriting from a class template specialization, the source of a synthesized template parameter might be an implicit specialization, whose inner function template is thus living at depth 0, for which we don’t want it to overflow too. --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 10 ++-- clang/test/SemaTemplate/deduction-guide.cpp | 48 +++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 9cfdb7596b660..6685fdd60dc09 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -376,12 +376,10 @@ struct ConvertConstructorToDeductionGuideTransform { if (NestedPattern) Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth()); auto [Depth, Index] = getDepthAndIndex(Param); - // Depth can still be 0 if FTD belongs to an explicit class template - // specialization with an empty template parameter list. In that case, - // we don't want the NewDepth to overflow, and it should remain 0. - assert(Depth || - cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext()) - ->isExplicitSpecialization()); + // Depth can be 0 if FTD belongs to a non-template class/a class + // template specialization with an empty template parameter list. In + // that case, we don't want the NewDepth to overflow, and it should + // remain 0. NamedDecl *NewParam = transformTemplateParameter( SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth ? Depth - 1 : 0); diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index ecd152abebd74..6db132ca37c7e 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -723,3 +723,51 @@ void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constr // CHECK-NEXT: `-ParmVarDecl {{.+}} 'T' } // namespace GH128691 + +namespace GH132616_DeductionGuide { + +template <class T> struct A { + template <class U> + A(U); +}; + +template <typename> +struct B : A<int> { + using A::A; +}; + +template <class T> +B(T) -> B<T>; + +B b(24); + +// CHECK-LABEL: Dumping GH132616_DeductionGuide::<deduction guide for B>: +// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for B> +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0 +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U +// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for B> 'auto (U) -> B<type-parameter-0-0>' +// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U' + +struct C { + template <class U> + C(U); +}; + +template <typename> +struct D : C { + using C::C; +}; + +template <class T> +D(T) -> D<T>; + +D d(24); + +// CHECK-LABEL: Dumping GH132616_DeductionGuide::<deduction guide for D>: +// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for D> +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0 +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U +// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for D> 'auto (U) -> D<type-parameter-0-0>' +// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U' + +} // namespace GH132616_DeductionGuide >From b7bef605503bc566dd0624b338d7ce6bec856fd3 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Mon, 24 Mar 2025 13:16:15 +0800 Subject: [PATCH 2/2] Drive-by fix for https://github.com/llvm/llvm-project/pull/132061#discussion_r2008756718 --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 6685fdd60dc09..3b2129e0df815 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -968,6 +968,19 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) { return {Template, AliasRhsTemplateArgs}; } +bool IsNonDeducedArgument(const TemplateArgument &TA) { + // The following cases indicate the template argument is non-deducible: + // 1. The result is null. E.g. When it comes from a default template + // argument that doesn't appear in the alias declaration. + // 2. The template parameter is a pack and that cannot be deduced from + // the arguments within the alias declaration. + // Non-deducible template parameters will persist in the transformed + // deduction guide. + return TA.isNull() || + (TA.getKind() == TemplateArgument::Pack && + llvm::any_of(TA.pack_elements(), IsNonDeducedArgument)); +} + // Build deduction guides for a type alias template from the given underlying // deduction guide F. FunctionTemplateDecl * @@ -1031,20 +1044,6 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef, AliasRhsTemplateArgs, TDeduceInfo, DeduceResults, /*NumberOfArgumentsMustMatch=*/false); - static std::function<bool(const TemplateArgument &TA)> IsNonDeducedArgument = - [](const TemplateArgument &TA) { - // The following cases indicate the template argument is non-deducible: - // 1. The result is null. E.g. When it comes from a default template - // argument that doesn't appear in the alias declaration. - // 2. The template parameter is a pack and that cannot be deduced from - // the arguments within the alias declaration. - // Non-deducible template parameters will persist in the transformed - // deduction guide. - return TA.isNull() || - (TA.getKind() == TemplateArgument::Pack && - llvm::any_of(TA.pack_elements(), IsNonDeducedArgument)); - }; - SmallVector<TemplateArgument> DeducedArgs; SmallVector<unsigned> NonDeducedTemplateParamsInFIndex; // !!NOTE: DeduceResults respects the sequence of template parameters of _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits