[clang] b8d1f3d - [Clang] Fix an integer overflow issue in computing CTAD's parameter depth (#128704)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 26 00:54:23 PST 2025
Author: Younan Zhang
Date: 2025-02-26T16:54:19+08:00
New Revision: b8d1f3d62746110ff0c969a136fc15f1d52f811d
URL: https://github.com/llvm/llvm-project/commit/b8d1f3d62746110ff0c969a136fc15f1d52f811d
DIFF: https://github.com/llvm/llvm-project/commit/b8d1f3d62746110ff0c969a136fc15f1d52f811d.diff
LOG: [Clang] Fix an integer overflow issue in computing CTAD's parameter depth (#128704)
There were some cases where we computed incorrect template parameter
depths for synthesized CTAD, invalid as they might be, we still
shouldn't crash anyway.
Technically the only scenario in which the inner function template's
depth is 0 is when it lives within an explicit template specialization,
where the template parameter list is empty.
Fixes https://github.com/llvm/llvm-project/issues/128691
Added:
Modified:
clang/lib/Sema/SemaTemplateDeductionGuide.cpp
clang/test/SemaTemplate/deduction-guide.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index b789824d97020..ee89ee8594bc4 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -377,8 +377,15 @@ 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());
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
More information about the cfe-commits
mailing list