Skip to content

[Clang] Fix the assertion condition after b8d1f3d6 #132669

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

Merged
merged 2 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 17 additions & 20 deletions clang/lib/Sema/SemaTemplateDeductionGuide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,10 @@ 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());
// Depth can be 0 if FTD belongs to a non-template class/a 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.
NamedDecl *NewParam = transformTemplateParameter(
SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
Depth ? Depth - 1 : 0);
Expand Down Expand Up @@ -970,6 +968,19 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
return {Template, AliasRhsTemplateArgs};
}

bool IsNonDeducedArgument(const TemplateArgument &TA) {
// The following cases indicate the template argument is non-deducible:
// 1. The result is null. E.g. When it comes from a default template
// argument that doesn't appear in the alias declaration.
// 2. The template parameter is a pack and that cannot be deduced from
// the arguments within the alias declaration.
// Non-deducible template parameters will persist in the transformed
// deduction guide.
return TA.isNull() ||
(TA.getKind() == TemplateArgument::Pack &&
llvm::any_of(TA.pack_elements(), IsNonDeducedArgument));
}

// Build deduction guides for a type alias template from the given underlying
// deduction guide F.
FunctionTemplateDecl *
Expand Down Expand Up @@ -1033,20 +1044,6 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
/*NumberOfArgumentsMustMatch=*/false);

static std::function<bool(const TemplateArgument &TA)> IsNonDeducedArgument =
[](const TemplateArgument &TA) {
// The following cases indicate the template argument is non-deducible:
// 1. The result is null. E.g. When it comes from a default template
// argument that doesn't appear in the alias declaration.
// 2. The template parameter is a pack and that cannot be deduced from
// the arguments within the alias declaration.
// Non-deducible template parameters will persist in the transformed
// deduction guide.
return TA.isNull() ||
(TA.getKind() == TemplateArgument::Pack &&
llvm::any_of(TA.pack_elements(), IsNonDeducedArgument));
};

SmallVector<TemplateArgument> DeducedArgs;
SmallVector<unsigned> NonDeducedTemplateParamsInFIndex;
// !!NOTE: DeduceResults respects the sequence of template parameters of
Expand Down
48 changes: 48 additions & 0 deletions clang/test/SemaTemplate/deduction-guide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,3 +723,51 @@ void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constr
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'T'

} // namespace GH128691

namespace GH132616_DeductionGuide {

template <class T> struct A {
template <class U>
A(U);
};

template <typename>
struct B : A<int> {
using A::A;
};

template <class T>
B(T) -> B<T>;

B b(24);

// CHECK-LABEL: Dumping GH132616_DeductionGuide::<deduction guide for B>:
// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for B>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for B> 'auto (U) -> B<type-parameter-0-0>'
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U'

struct C {
template <class U>
C(U);
};

template <typename>
struct D : C {
using C::C;
};

template <class T>
D(T) -> D<T>;

D d(24);

// CHECK-LABEL: Dumping GH132616_DeductionGuide::<deduction guide for D>:
// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for D>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for D> 'auto (U) -> D<type-parameter-0-0>'
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U'

} // namespace GH132616_DeductionGuide