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

Reply via email to