https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/149782
>From 32be32e2ae072f920389c61e42b9e392a6b92798 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Mon, 21 Jul 2025 17:17:48 +0800 Subject: [PATCH 1/2] [Clang] Fix a partial ordering bug involving CTAD injected template arguments --- clang/lib/Sema/SemaTemplateDeduction.cpp | 12 +++++++++--- clang/test/SemaTemplate/deduction-guide.cpp | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index d09a72b71b805..f990e609d9823 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5525,6 +5525,8 @@ static TemplateDeductionResult CheckDeductionConsistency( // FIXME: A substitution can be incomplete on a non-structural part of the // type. Use the canonical type for now, until the TemplateInstantiator can // deal with that. + if (auto *Injected = P->getAs<InjectedClassNameType>()) + P = Injected->getInjectedSpecializationType(); QualType InstP = S.SubstType(P.getCanonicalType(), MLTAL, FTD->getLocation(), FTD->getDeclName(), &IsIncompleteSubstitution); if (InstP.isNull() && !IsIncompleteSubstitution) @@ -5539,9 +5541,13 @@ static TemplateDeductionResult CheckDeductionConsistency( if (auto *PA = dyn_cast<PackExpansionType>(A); PA && !isa<PackExpansionType>(InstP)) A = PA->getPattern(); - if (!S.Context.hasSameType( - S.Context.getUnqualifiedArrayType(InstP.getNonReferenceType()), - S.Context.getUnqualifiedArrayType(A.getNonReferenceType()))) + auto T1 = S.Context.getUnqualifiedArrayType(InstP.getNonReferenceType()); + auto T2 = S.Context.getUnqualifiedArrayType(A.getNonReferenceType()); + if (auto *Injected = T1->getAs<InjectedClassNameType>()) + T1 = Injected->getInjectedSpecializationType(); + if (auto *Injected = T2->getAs<InjectedClassNameType>()) + T2 = Injected->getInjectedSpecializationType(); + if (!S.Context.hasSameType(T1, T2)) return TemplateDeductionResult::NonDeducedMismatch; return TemplateDeductionResult::Success; } diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index 0953f647426fa..f6bc6ee3673c2 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -966,3 +966,19 @@ Expand<Type, Invocable<>> _{}; // CHECK-NEXT: | `-ParmVarDecl {{.+}} 'T...' pack } + +namespace GH134613 { +template <typename R> struct Foo { + using value_type = R; + + Foo() = default; + Foo(Foo<Foo<R>> &&rhs) {} +}; + +void main() { + auto r1 = Foo(Foo<Foo<int>>{}); + + static_assert(__is_same(decltype(r1)::value_type, int)); +} + +} >From 0fa71d3eb2f03e115da5ebd97bef52226affbd1b Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Wed, 23 Jul 2025 18:47:58 +0800 Subject: [PATCH 2/2] Apply suggestions --- clang/lib/Sema/SemaTemplateDeduction.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index f990e609d9823..ce78ecc2d4a2d 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5525,8 +5525,15 @@ static TemplateDeductionResult CheckDeductionConsistency( // FIXME: A substitution can be incomplete on a non-structural part of the // type. Use the canonical type for now, until the TemplateInstantiator can // deal with that. - if (auto *Injected = P->getAs<InjectedClassNameType>()) - P = Injected->getInjectedSpecializationType(); + + // Workaround: Implicit deduction guides use InjectedClassNameTypes, whereas + // the explicit guides don't. The substitution doesn't transform these types, + // so let it transform their specializations instead. + bool IsDeductionGuide = isa<CXXDeductionGuideDecl>(FTD->getTemplatedDecl()); + if (IsDeductionGuide) { + if (auto *Injected = P->getAs<InjectedClassNameType>()) + P = Injected->getInjectedSpecializationType(); + } QualType InstP = S.SubstType(P.getCanonicalType(), MLTAL, FTD->getLocation(), FTD->getDeclName(), &IsIncompleteSubstitution); if (InstP.isNull() && !IsIncompleteSubstitution) @@ -5543,10 +5550,12 @@ static TemplateDeductionResult CheckDeductionConsistency( A = PA->getPattern(); auto T1 = S.Context.getUnqualifiedArrayType(InstP.getNonReferenceType()); auto T2 = S.Context.getUnqualifiedArrayType(A.getNonReferenceType()); - if (auto *Injected = T1->getAs<InjectedClassNameType>()) - T1 = Injected->getInjectedSpecializationType(); - if (auto *Injected = T2->getAs<InjectedClassNameType>()) - T2 = Injected->getInjectedSpecializationType(); + if (IsDeductionGuide) { + if (auto *Injected = T1->getAs<InjectedClassNameType>()) + T1 = Injected->getInjectedSpecializationType(); + if (auto *Injected = T2->getAs<InjectedClassNameType>()) + T2 = Injected->getInjectedSpecializationType(); + } if (!S.Context.hasSameType(T1, T2)) return TemplateDeductionResult::NonDeducedMismatch; return TemplateDeductionResult::Success; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits