[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 23 22:19:21 PDT 2025
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/132669
>From 27a42c2b5186b8bd5a71ca7e8bc574439d21e7fd Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at 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 | 12 +++++----
clang/test/SemaTemplate/deduction-guide.cpp | 26 +++++++++++++++++++
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 9cfdb7596b660..e20130a33f368 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -376,12 +376,14 @@ 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.
+ // Depth can be 0 if FTD belongs to a class template specialization with
+ // an empty template parameter list (i.e. either an explicit full
+ // specialization or an implicit specialization) In that case, we don't
+ // want the NewDepth to overflow, and it should remain 0.
assert(Depth ||
- cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext())
- ->isExplicitSpecialization());
+ isa<ClassTemplateDecl *>(
+ cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext())
+ ->getSpecializedTemplateOrPartial()));
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..95e740a026550 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -723,3 +723,29 @@ 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'
+
+} // namespace GH132616_DeductionGuide
>From 49f2a7e56874a7d097e1236942089765e016f755 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at 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 e20130a33f368..3d06663dc8054 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -972,6 +972,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 *
@@ -1035,20 +1048,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
More information about the cfe-commits
mailing list