Skip to content

Commit 27a42c2

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 27a42c2

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

clang/lib/Sema/SemaTemplateDeductionGuide.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,12 +376,14 @@ 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.
379+
// Depth can be 0 if FTD belongs to a class template specialization with
380+
// an empty template parameter list (i.e. either an explicit full
381+
// specialization or an implicit specialization) In that case, we don't
382+
// want the NewDepth to overflow, and it should remain 0.
382383
assert(Depth ||
383-
cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext())
384-
->isExplicitSpecialization());
384+
isa<ClassTemplateDecl *>(
385+
cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext())
386+
->getSpecializedTemplateOrPartial()));
385387
NamedDecl *NewParam = transformTemplateParameter(
386388
SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
387389
Depth ? Depth - 1 : 0);

clang/test/SemaTemplate/deduction-guide.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,3 +723,29 @@ 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+
} // namespace GH132616_DeductionGuide

0 commit comments

Comments
 (0)