Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clang] Fix an integer overflow issue in computing CTAD's parameter depth #128704

Merged
merged 2 commits into from
Feb 26, 2025

Conversation

zyn0217
Copy link
Contributor

@zyn0217 zyn0217 commented Feb 25, 2025

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 #128691

@zyn0217 zyn0217 requested review from cor3ntin and hokein February 25, 2025 11:59
Copy link
Collaborator

@hokein hokein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick fix!

@hokein
Copy link
Collaborator

hokein commented Feb 25, 2025

(We should have been doing this wrong prior to 20, but it didn't crash because it called Decl::getTemplateDepth(), which returns 0 for the transformed template parameter declaration)

I think you're right. The depth is already incorrect in clang19 etc. https://godbolt.org/z/d9xhxh3EM

 |-TemplateTypeParmDecl 0x175b5b88 <line:6:13, col:22> col:22 typename depth 32767 index 1 T

Copy link
Collaborator

@hokein hokein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to add a release note as it fixes an existing issue.

@zyn0217
Copy link
Contributor Author

zyn0217 commented Feb 26, 2025

Need to add a release note as it fixes an existing issue.

Do you think we need a backport? If so, we can add the release note in the backport PR

@zyn0217 zyn0217 marked this pull request as ready for review February 26, 2025 04:40
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Feb 26, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 26, 2025

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

Changes

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 #128691


Full diff: https://github.com/llvm/llvm-project/pull/128704.diff

2 Files Affected:

  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+5-1)
  • (modified) clang/test/SemaTemplate/deduction-guide.cpp (+32)
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

@hokein
Copy link
Collaborator

hokein commented Feb 26, 2025

Need to add a release note as it fixes an existing issue.

Do you think we need a backport? If so, we can add the release note in the backport PR

This is not a regression, but we have a change in clang20 which exposes this issue in the assertion-build clang. I'd prefer a backport.

@zyn0217
Copy link
Contributor Author

zyn0217 commented Feb 26, 2025

I'll go ahead and merge this, and add the release note in the backport PR - else I have to tackle annoying merge conflicts

@zyn0217 zyn0217 merged commit b8d1f3d into llvm:main Feb 26, 2025
6 of 10 checks passed
zyn0217 added a commit to zyn0217/llvm-project that referenced this pull request Feb 26, 2025
…epth (llvm#128704)

Backports b8d1f3d.

This fixes a potential integer overflow bug that has been around for
many versions and was exposed by my patch recently. So we think it
warrants a backport
@zyn0217
Copy link
Contributor Author

zyn0217 commented Feb 26, 2025

(Backport PR at #128845)

swift-ci pushed a commit to swiftlang/llvm-project that referenced this pull request Mar 13, 2025
…epth (llvm#128704)

Backports b8d1f3d.

This fixes a potential integer overflow bug that has been around for
many versions and was exposed by my patch recently. So we think it
warrants a backport
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
3 participants