[clang] [Clang] Fix an integer overflow issue in computing CTAD's parameter depth (PR #128704)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 26 00:51:31 PST 2025
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/128704
>From eeae197a06bf4a7c23d8c517dc87807608d8dd86 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Tue, 25 Feb 2025 19:56:40 +0800
Subject: [PATCH 1/2] [Clang] Fix an integer overflow issue in computing CTAD's
parameter depth
---
clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 6 +++-
clang/test/SemaTemplate/deduction-guide.cpp | 32 +++++++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index b789824d97020..0632defbd844f 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -377,8 +377,12 @@ struct ConvertConstructorToDeductionGuideTransform {
if (NestedPattern)
Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
auto [Depth, Index] = getDepthAndIndex(Param);
+ assert(Depth ||
+ cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext())
+ ->isExplicitSpecialization());
NamedDecl *NewParam = transformTemplateParameter(
- SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth - 1);
+ SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
+ Depth ? Depth - 1 : 0);
if (!NewParam)
return nullptr;
// Constraints require that we substitute depth-1 arguments
diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp
index a4c523595fca2..ecd152abebd74 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -691,3 +691,35 @@ Test test(42);
// CHECK-NEXT: | `-ParmVarDecl {{.*}} 'auto:1'
} // namespace GH122134
+
+namespace GH128691 {
+
+template <typename = void>
+class NewDeleteAllocator;
+
+template <>
+struct NewDeleteAllocator<> {
+ template <typename T>
+ NewDeleteAllocator(T); // expected-note {{candidate template ignored}} \
+ // expected-note {{implicit deduction guide declared as}}
+};
+
+template <typename>
+struct NewDeleteAllocator : NewDeleteAllocator<> { // expected-note {{candidate template ignored}} \
+ // expected-note {{implicit deduction guide declared as}}
+ using NewDeleteAllocator<>::NewDeleteAllocator;
+};
+
+void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constructor or deduction guide}}
+
+// CHECK-LABEL: Dumping GH128691::<deduction guide for NewDeleteAllocator>:
+// CHECK-NEXT: FunctionTemplateDecl {{.+}} <deduction guide for NewDeleteAllocator>
+// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
+// CHECK-NEXT: | `-TemplateArgument type 'void'
+// CHECK-NEXT: | |-inherited from TemplateTypeParm {{.+}} depth 0 index 0
+// CHECK-NEXT: | `-BuiltinType {{.+}} 'void'
+// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 1 T
+// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <deduction guide for NewDeleteAllocator> 'auto (T) -> NewDeleteAllocator<type-parameter-0-0>'
+// CHECK-NEXT: `-ParmVarDecl {{.+}} 'T'
+
+} // namespace GH128691
>From cfc512663cb03e79f923fd61b034e0118fcc1b22 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Wed, 26 Feb 2025 16:50:42 +0800
Subject: [PATCH 2/2] Add brief explanations
---
clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 0632defbd844f..ee89ee8594bc4 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -377,6 +377,9 @@ 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());
More information about the cfe-commits
mailing list