Skip to content

release/21.x: [Clang] Fix a partial ordering bug involving CTAD injected template arguments (#149782) #151075

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 1 commit into from
Jul 29, 2025

Conversation

llvmbot
Copy link
Member

@llvmbot llvmbot commented Jul 29, 2025

Backport 07faafe

Requested by: @zyn0217

@llvmbot
Copy link
Member Author

llvmbot commented Jul 29, 2025

@shafik What do you think about merging this PR to the release branch?

@llvmbot llvmbot requested a review from shafik July 29, 2025 02:42
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jul 29, 2025
@zyn0217 zyn0217 requested a review from cor3ntin July 29, 2025 02:42
@llvmbot
Copy link
Member Author

llvmbot commented Jul 29, 2025

@llvm/pr-subscribers-clang

Author: None (llvmbot)

Changes

Backport 07faafe

Requested by: @zyn0217


Full diff: https://github.com/llvm/llvm-project/pull/151075.diff

2 Files Affected:

  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+18-3)
  • (modified) clang/test/SemaTemplate/deduction-guide.cpp (+16)
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index d09a72b71b805..ce78ecc2d4a2d 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5525,6 +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.
+
+  // 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)
@@ -5539,9 +5548,15 @@ 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 (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;
 }
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));
+}
+
+}

@tru tru moved this from Needs Triage to Needs Review in LLVM Release Status Jul 29, 2025
@github-project-automation github-project-automation bot moved this from Needs Review to Needs Merge in LLVM Release Status Jul 29, 2025
…rguments (llvm#149782)

The synthesized deduction guides use injected template arguments for
distinguishment of explicit and implicit deduction guides.

In partial ordering, we may substitute into these injected types when
checking consistency. Properly substituting them needs the instantiated
class template specializations which isn't the case at that point. So
instead, we check their template specialization types.

No release note because I think we want a backport, after baking it for
a couple of days.

Fixes llvm#134613

(cherry picked from commit 07faafe)
@tru tru merged commit 2ec38ab into llvm:release/21.x Jul 29, 2025
1 check was pending
@github-project-automation github-project-automation bot moved this from Needs Merge to Done in LLVM Release Status Jul 29, 2025
Copy link

@zyn0217 (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
Development

Successfully merging this pull request may close these issues.

4 participants