Skip to content

Commit 63e63f3

Browse files
zyn0217tstellar
authored andcommitted
[Clang] Fix an integer overflow issue in computing CTAD's parameter depth (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
1 parent b09b05b commit 63e63f3

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

clang/docs/ReleaseNotes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,7 @@ Bug Fixes to C++ Support
10581058
- Fixed a substitution bug in transforming CTAD aliases when the type alias contains a non-pack template argument
10591059
corresponding to a pack parameter (#GH124715)
10601060
- Clang is now better at keeping track of friend function template instance contexts. (#GH55509)
1061+
- Fixed an integer overflow bug in computing template parameter depths when synthesizing CTAD guides. (#GH128691)
10611062

10621063
Bug Fixes to AST Handling
10631064
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateDeductionGuide.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,15 @@ struct ConvertConstructorToDeductionGuideTransform {
377377
if (NestedPattern)
378378
Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
379379
auto [Depth, Index] = getDepthAndIndex(Param);
380+
// Depth can still be 0 if FTD belongs to an explicit class template
381+
// specialization with an empty template parameter list. In that case,
382+
// we don't want the NewDepth to overflow, and it should remain 0.
383+
assert(Depth ||
384+
cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext())
385+
->isExplicitSpecialization());
380386
NamedDecl *NewParam = transformTemplateParameter(
381-
SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth - 1);
387+
SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
388+
Depth ? Depth - 1 : 0);
382389
if (!NewParam)
383390
return nullptr;
384391
// Constraints require that we substitute depth-1 arguments

clang/test/SemaTemplate/deduction-guide.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -691,3 +691,35 @@ Test test(42);
691691
// CHECK-NEXT: | `-ParmVarDecl {{.*}} 'auto:1'
692692

693693
} // namespace GH122134
694+
695+
namespace GH128691 {
696+
697+
template <typename = void>
698+
class NewDeleteAllocator;
699+
700+
template <>
701+
struct NewDeleteAllocator<> {
702+
template <typename T>
703+
NewDeleteAllocator(T); // expected-note {{candidate template ignored}} \
704+
// expected-note {{implicit deduction guide declared as}}
705+
};
706+
707+
template <typename>
708+
struct NewDeleteAllocator : NewDeleteAllocator<> { // expected-note {{candidate template ignored}} \
709+
// expected-note {{implicit deduction guide declared as}}
710+
using NewDeleteAllocator<>::NewDeleteAllocator;
711+
};
712+
713+
void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constructor or deduction guide}}
714+
715+
// CHECK-LABEL: Dumping GH128691::<deduction guide for NewDeleteAllocator>:
716+
// CHECK-NEXT: FunctionTemplateDecl {{.+}} <deduction guide for NewDeleteAllocator>
717+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
718+
// CHECK-NEXT: | `-TemplateArgument type 'void'
719+
// CHECK-NEXT: | |-inherited from TemplateTypeParm {{.+}} depth 0 index 0
720+
// CHECK-NEXT: | `-BuiltinType {{.+}} 'void'
721+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 1 T
722+
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <deduction guide for NewDeleteAllocator> 'auto (T) -> NewDeleteAllocator<type-parameter-0-0>'
723+
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'T'
724+
725+
} // namespace GH128691

0 commit comments

Comments
 (0)