https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/125478
>From 4af8e1985c4882e1083cd522eb955f69066bd15e Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Mon, 3 Feb 2025 11:55:17 +0100 Subject: [PATCH 1/3] [clang] CTAD alias: Respecte explicit deduction guides defined after the first use of the alias template. --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 33 ++++++++++++++----- clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 13 ++++++-- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 0d079677eecc568..f5884f964d6fbd5 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -740,6 +740,24 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) { return false; } +// Returns all source deduction guides associated with the declared +// deduction guides that have the specified deduction guide name. +llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides(DeclarationName Name, + DeclContext *DC) { + assert(Name.getNameKind() == + DeclarationName::NameKind::CXXDeductionGuideName && + "name must be a deduction guide name"); + llvm::DenseSet<const NamedDecl *> Result; + for (auto *D : DC->lookup(Name)) { + if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) + D = FTD->getTemplatedDecl(); + + if (const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) + Result.insert(GD->getSourceDeductionGuide()); + } + return Result; +} + // Build the associated constraints for the alias deduction guides. // C++ [over.match.class.deduct]p3.3: // The associated constraints ([temp.constr.decl]) are the conjunction of the @@ -1191,13 +1209,10 @@ void DeclareImplicitDeductionGuidesForTypeAlias( if (AliasTemplate->isInvalidDecl()) return; auto &Context = SemaRef.Context; - // FIXME: if there is an explicit deduction guide after the first use of the - // type alias usage, we will not cover this explicit deduction guide. fix this - // case. - if (hasDeclaredDeductionGuides( - Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), - AliasTemplate->getDeclContext())) - return; + auto SourceDeductionGuides = getSourceDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext()); + auto [Template, AliasRhsTemplateArgs] = getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate); if (!Template) @@ -1210,6 +1225,8 @@ void DeclareImplicitDeductionGuidesForTypeAlias( for (auto *G : Guides) { if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) { + if (SourceDeductionGuides.contains(DG)) + continue; // The deduction guide is a non-template function decl, we just clone it. auto *FunctionType = SemaRef.Context.getTrivialTypeSourceInfo(DG->getType()); @@ -1252,7 +1269,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias( continue; } FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G); - if (!F) + if (!F || SourceDeductionGuides.contains(F->getTemplatedDecl())) continue; // The **aggregate** deduction guides are handled in a different code path // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index 2d43e46b9e3d76b..6a004769a6d4d61 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -237,8 +237,17 @@ static_assert(__is_same(decltype(s.t), int)); // explicit deduction guide. Foo(int) -> Foo<X>; AFoo s2{i}; -// FIXME: the type should be X because of the above explicit deduction guide. -static_assert(__is_same(decltype(s2.t), int)); +static_assert(__is_same(decltype(s2.t), X)); + + +template<class T> +using BFoo = AFoo<T>; +static_assert(__is_same(decltype(BFoo(i).t), X)); + + +Foo(double) -> Foo<int>; +static_assert(__is_same(decltype(AFoo(1.0).t), int)); +static_assert(__is_same(decltype(BFoo(1.0).t), int)); } // namespace test16 namespace test17 { >From abc88828cba91ae54244b8582e60d87c7980e555 Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Mon, 3 Feb 2025 14:29:06 +0100 Subject: [PATCH 2/3] Address review comments. --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index f5884f964d6fbd5..e5931f4684a57d8 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -752,8 +752,12 @@ llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides(DeclarationName Name, if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) D = FTD->getTemplatedDecl(); - if (const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) + if (const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) { + assert(GD->getSourceDeductionGuide() && + "deduction guide for alias template must have a source deduction " + "guide"); Result.insert(GD->getSourceDeductionGuide()); + } } return Result; } @@ -1209,14 +1213,14 @@ void DeclareImplicitDeductionGuidesForTypeAlias( if (AliasTemplate->isInvalidDecl()) return; auto &Context = SemaRef.Context; - auto SourceDeductionGuides = getSourceDeductionGuides( - Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), - AliasTemplate->getDeclContext()); - auto [Template, AliasRhsTemplateArgs] = getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate); if (!Template) return; + auto SourceDeductionGuides = getSourceDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext()); + DeclarationNameInfo NameInfo( Context.DeclarationNames.getCXXDeductionGuideName(Template), Loc); LookupResult Guides(SemaRef, NameInfo, clang::Sema::LookupOrdinaryName); >From 17505514f55f791f8f509df78bfd42ecc75e3fae Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Mon, 10 Feb 2025 14:43:08 +0100 Subject: [PATCH 3/3] Add a test case for explicit template deduction guides. --- clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index 6a004769a6d4d61..37dca2215af6ba3 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -234,16 +234,19 @@ int i = 0; AFoo s{i}; static_assert(__is_same(decltype(s.t), int)); -// explicit deduction guide. -Foo(int) -> Foo<X>; -AFoo s2{i}; -static_assert(__is_same(decltype(s2.t), X)); - - template<class T> using BFoo = AFoo<T>; -static_assert(__is_same(decltype(BFoo(i).t), X)); +// template explicit deduction guide. +template<class T> +Foo(T) -> Foo<float>; +static_assert(__is_same(decltype(AFoo(i).t), float)); +static_assert(__is_same(decltype(BFoo(i).t), float)); + +// explicit deduction guide. +Foo(int) -> Foo<X>; +static_assert(__is_same(decltype(AFoo(i).t), X)); +static_assert(__is_same(decltype(BFoo(i).t), X)); Foo(double) -> Foo<int>; static_assert(__is_same(decltype(AFoo(1.0).t), int)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits