https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/186735

>From d9166d1e298b6e464e0b7da445d3dc7ac158e36d Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Mon, 16 Mar 2026 12:49:49 +0800
Subject: [PATCH 1/3] [Clang] Fix a concept subsumption bug when template
 depths are adjusted

We cannot reuse the cached normalization results if any template depth
adjustments (in subsumption checking) are involved.
---
 clang/include/clang/Sema/SemaConcept.h |  3 ++-
 clang/lib/Sema/SemaConcept.cpp         | 11 +++++++----
 clang/test/SemaTemplate/concepts.cpp   | 19 +++++++++++++++++++
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Sema/SemaConcept.h 
b/clang/include/clang/Sema/SemaConcept.h
index bdd997b18cb08..e6644f1bd1bee 100644
--- a/clang/include/clang/Sema/SemaConcept.h
+++ b/clang/include/clang/Sema/SemaConcept.h
@@ -431,7 +431,8 @@ class SubsumptionChecker {
   std::optional<bool> Subsumes(const NamedDecl *DP,
                                ArrayRef<AssociatedConstraint> P,
                                const NamedDecl *DQ,
-                               ArrayRef<AssociatedConstraint> Q);
+                               ArrayRef<AssociatedConstraint> Q,
+                               bool DepthAdjusted);
 
   bool Subsumes(const NormalizedConstraint *P, const NormalizedConstraint *Q);
 
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 38791940247cb..16cbec22c823b 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -2544,7 +2544,8 @@ bool Sema::IsAtLeastAsConstrained(const NamedDecl *D1,
   }
 
   SubsumptionChecker SC(*this);
-  std::optional<bool> Subsumes = SC.Subsumes(D1, AC1, D2, AC2);
+  std::optional<bool> Subsumes =
+      SC.Subsumes(D1, AC1, D2, AC2, /*DepthAdjusted=*/Depth1 != Depth2);
   if (!Subsumes) {
     // Normalization failed
     return true;
@@ -2778,14 +2779,16 @@ void 
SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause C) {
 
 std::optional<bool> SubsumptionChecker::Subsumes(
     const NamedDecl *DP, ArrayRef<AssociatedConstraint> P, const NamedDecl *DQ,
-    ArrayRef<AssociatedConstraint> Q) {
+    ArrayRef<AssociatedConstraint> Q, bool DepthAdjusted) {
   const NormalizedConstraint *PNormalized =
-      SemaRef.getNormalizedAssociatedConstraints(DP, P);
+      SemaRef.getNormalizedAssociatedConstraints(DepthAdjusted ? nullptr : DP,
+                                                 P);
   if (!PNormalized)
     return std::nullopt;
 
   const NormalizedConstraint *QNormalized =
-      SemaRef.getNormalizedAssociatedConstraints(DQ, Q);
+      SemaRef.getNormalizedAssociatedConstraints(DepthAdjusted ? nullptr : DQ,
+                                                 Q);
   if (!QNormalized)
     return std::nullopt;
 
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index 1d2ada3e0a398..628499bebea83 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1659,6 +1659,25 @@ void foo() { call(""); }
 
 }
 
+namespace GH186624 {
+
+template <class T>
+concept C = __is_unsigned(T);
+
+template <C T>
+struct encoder_interface {};
+
+template <template <C> class CodecInterface, C T>
+CodecInterface<T>* create_codec() {
+  return nullptr;
+}
+
+encoder_interface<unsigned>* create_encoder() {
+  return create_codec<encoder_interface, unsigned>();
+}
+
+}
+
 namespace GH170856 {
 
 template <unsigned N, unsigned M> struct symbol_text {

>From 3e6274c4055cac9bb2634c6970e7c2af13bc18d8 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Mon, 16 Mar 2026 19:35:49 +0800
Subject: [PATCH 2/3] Do not break ABI

---
 clang/include/clang/Sema/SemaConcept.h |  3 +--
 clang/lib/Sema/SemaConcept.cpp         | 20 +++++++++++++-------
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/Sema/SemaConcept.h 
b/clang/include/clang/Sema/SemaConcept.h
index e6644f1bd1bee..bdd997b18cb08 100644
--- a/clang/include/clang/Sema/SemaConcept.h
+++ b/clang/include/clang/Sema/SemaConcept.h
@@ -431,8 +431,7 @@ class SubsumptionChecker {
   std::optional<bool> Subsumes(const NamedDecl *DP,
                                ArrayRef<AssociatedConstraint> P,
                                const NamedDecl *DQ,
-                               ArrayRef<AssociatedConstraint> Q,
-                               bool DepthAdjusted);
+                               ArrayRef<AssociatedConstraint> Q);
 
   bool Subsumes(const NormalizedConstraint *P, const NormalizedConstraint *Q);
 
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 16cbec22c823b..0cd35ef6d90c2 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -14,6 +14,7 @@
 #include "TreeTransform.h"
 #include "clang/AST/ASTConcept.h"
 #include "clang/AST/ASTLambda.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprConcepts.h"
 #include "clang/AST/RecursiveASTVisitor.h"
@@ -2544,8 +2545,15 @@ bool Sema::IsAtLeastAsConstrained(const NamedDecl *D1,
   }
 
   SubsumptionChecker SC(*this);
-  std::optional<bool> Subsumes =
-      SC.Subsumes(D1, AC1, D2, AC2, /*DepthAdjusted=*/Depth1 != Depth2);
+  // Associated declarations are used as a cache key in the event they were
+  // normalized earlier during concept checking. However we cannot reuse these
+  // cached results if any of the template depths have been adjusted.
+  const NamedDecl *DeclAC1 = D1, *DeclAC2 = D2;
+  if (Depth2 > Depth1)
+    DeclAC1 = nullptr;
+  else if (Depth1 > Depth2)
+    DeclAC2 = nullptr;
+  std::optional<bool> Subsumes = SC.Subsumes(DeclAC1, AC1, DeclAC2, AC2);
   if (!Subsumes) {
     // Normalization failed
     return true;
@@ -2779,16 +2787,14 @@ void 
SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause C) {
 
 std::optional<bool> SubsumptionChecker::Subsumes(
     const NamedDecl *DP, ArrayRef<AssociatedConstraint> P, const NamedDecl *DQ,
-    ArrayRef<AssociatedConstraint> Q, bool DepthAdjusted) {
+    ArrayRef<AssociatedConstraint> Q) {
   const NormalizedConstraint *PNormalized =
-      SemaRef.getNormalizedAssociatedConstraints(DepthAdjusted ? nullptr : DP,
-                                                 P);
+      SemaRef.getNormalizedAssociatedConstraints(DP, P);
   if (!PNormalized)
     return std::nullopt;
 
   const NormalizedConstraint *QNormalized =
-      SemaRef.getNormalizedAssociatedConstraints(DepthAdjusted ? nullptr : DQ,
-                                                 Q);
+      SemaRef.getNormalizedAssociatedConstraints(DQ, Q);
   if (!QNormalized)
     return std::nullopt;
 

>From 969767ddaca6de9f1f3b5a30e7ccb33764171d77 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Mon, 16 Mar 2026 19:43:57 +0800
Subject: [PATCH 3/3] Remove header

---
 clang/lib/Sema/SemaConcept.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 0cd35ef6d90c2..ce5ee934c6445 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -14,7 +14,6 @@
 #include "TreeTransform.h"
 #include "clang/AST/ASTConcept.h"
 #include "clang/AST/ASTLambda.h"
-#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprConcepts.h"
 #include "clang/AST/RecursiveASTVisitor.h"

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to