Skip to content

Commit 2894090

Browse files
committed
[Clang] Fix the assertion condition after b8d1f3d
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.
1 parent 868c89f commit 2894090

File tree

2 files changed

+52
-6
lines changed

2 files changed

+52
-6
lines changed

clang/lib/Sema/SemaTemplateDeductionGuide.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -376,12 +376,10 @@ struct ConvertConstructorToDeductionGuideTransform {
376376
if (NestedPattern)
377377
Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
378378
auto [Depth, Index] = getDepthAndIndex(Param);
379-
// Depth can still be 0 if FTD belongs to an explicit class template
380-
// specialization with an empty template parameter list. In that case,
381-
// we don't want the NewDepth to overflow, and it should remain 0.
382-
assert(Depth ||
383-
cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext())
384-
->isExplicitSpecialization());
379+
// Depth can be 0 if FTD belongs to a non-template class/a class
380+
// template specialization with an empty template parameter list. In
381+
// that case, we don't want the NewDepth to overflow, and it should
382+
// remain 0.
385383
NamedDecl *NewParam = transformTemplateParameter(
386384
SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
387385
Depth ? Depth - 1 : 0);

clang/test/SemaTemplate/deduction-guide.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,3 +723,51 @@ void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constr
723723
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'T'
724724

725725
} // namespace GH128691
726+
727+
namespace GH132616_DeductionGuide {
728+
729+
template <class T> struct A {
730+
template <class U>
731+
A(U);
732+
};
733+
734+
template <typename>
735+
struct B : A<int> {
736+
using A::A;
737+
};
738+
739+
template <class T>
740+
B(T) -> B<T>;
741+
742+
B b(24);
743+
744+
// CHECK-LABEL: Dumping GH132616_DeductionGuide::<deduction guide for B>:
745+
// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for B>
746+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
747+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
748+
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for B> 'auto (U) -> B<type-parameter-0-0>'
749+
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U'
750+
751+
struct C {
752+
template <class U>
753+
C(U);
754+
};
755+
756+
template <typename>
757+
struct D : C {
758+
using C::C;
759+
};
760+
761+
template <class T>
762+
D(T) -> D<T>;
763+
764+
D d(24);
765+
766+
// CHECK-LABEL: Dumping GH132616_DeductionGuide::<deduction guide for D>:
767+
// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for D>
768+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
769+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
770+
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for D> 'auto (U) -> D<type-parameter-0-0>'
771+
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U'
772+
773+
} // namespace GH132616_DeductionGuide

0 commit comments

Comments
 (0)