https://github.com/zyn0217 created 
https://github.com/llvm/llvm-project/pull/208663

When building parameter mapping, both substitution and CheckTemplateArguments 
were marked as ParameterMappingSubstitution, while CheckTemplateArguments could 
also substitute into default arguments eagerly such that some type constraints 
were transformed too early.

It turned out that we don't have to enforce that rebuild in 
SubstTypeConstraint, so this reverts that behavior.

Fixes https://github.com/llvm/llvm-project/issues/197597

>From 6365249629b7e2b8a90de3a15c788d6e94f14421 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Fri, 10 Jul 2026 16:47:55 +0800
Subject: [PATCH] [Clang] Fix a bug in parameter mapping substitution

When building parameter mapping, both substitution and CheckTemplateArguments
were marked as InstantiatingTemplate::ParameterMappingSubstitution, while
CheckTemplateArguments could also substitute into default arguments eagerly
so that some type constrains can be also transformed too early.

It turned out that we don't have to enforce a constraint rebuild in
SubstTypeConstraints, so this reverts that behavior.
---
 clang/docs/ReleaseNotes.md                    |  1 +
 clang/lib/Sema/SemaTemplateInstantiate.cpp    |  2 +-
 .../concepts-no-early-substitution.cpp        | 58 +++++++++++++++++++
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 4d7d9f2909096..8537b6107358b 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -815,6 +815,7 @@ latest release, please see the [Clang Web 
Site](https://clang.llvm.org) or the
 - Fixed a preprocessor assertion failure triggered when parsing an invalid 
template-id starting with `::template operator`. (#GH186582)
 - Fixed a crash when a function template is defined as a non-template friend 
with a global scope qualifier. (#GH185341)
 - Clang now rejects constant template parameters with block pointer types, 
since these are not implemented anyway and would lead to crashes. (#GH189247)
+- Fixed some concept bugs introduced in Clang 22 (#GH197597)
 - Clang no longer reject call expressions whose type is a not-yet-deduced auto 
type. (#GH207565)
 - Fixed a crash on error recovery when dealing with invalid templates. 
(#GH183075)
 - Fixed a crash when instantiating `requires` expressions involving 
substitution failures in C++ concepts. (#GH176402)
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index a77ea5fd3dfff..a68a864ea59e2 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3075,7 +3075,7 @@ bool Sema::SubstTypeConstraint(
   const ASTTemplateArgumentListInfo *TemplArgInfo =
       TC->getTemplateArgsAsWritten();
 
-  if (!EvaluateConstraints && !inParameterMappingSubstitution()) {
+  if (!EvaluateConstraints) {
     UnsignedOrNone Index = TC->getArgPackSubstIndex();
     bool ContainsUnexpandedPack =
         TemplArgInfo &&
diff --git a/clang/test/SemaTemplate/concepts-no-early-substitution.cpp 
b/clang/test/SemaTemplate/concepts-no-early-substitution.cpp
index 9e576f16a263b..37f8b9485c3e2 100644
--- a/clang/test/SemaTemplate/concepts-no-early-substitution.cpp
+++ b/clang/test/SemaTemplate/concepts-no-early-substitution.cpp
@@ -31,3 +31,61 @@ struct View {
 
 struct Subrange : View<void> {};
 static_assert(Concept<Subrange>);
+
+namespace GH197597 {
+
+template <class> struct iterator_traits;
+template <class _Tp> struct iterator_traits<_Tp *> {
+  typedef _Tp value_type;
+};
+template <class _Ip>
+concept contiguous_iterator =
+    requires { typename iterator_traits<_Ip>::value_type; };
+template <class _CharT> class basic_format_context;
+template <class _Tp, class _Context,
+          class = _Context::template formatter_type<_Tp>>
+concept __formattable_with = requires(_Context __fc) { __fc; };
+template <class _Tp, class _CharT>
+concept formattable = __formattable_with<_Tp, basic_format_context<_CharT>>;
+template <class _CharT> struct __retarget_buffer {
+  struct __iterator {
+    __retarget_buffer *__buffer_;
+  };
+  template <contiguous_iterator _Iterator> void __transform(_Iterator);
+};
+template <class> struct formatter;
+template <class _Context> struct __basic_format_arg_value {
+  struct __handle {
+    template <class _Tp>
+    __handle(_Tp)
+        : __format_([](_Context &__ctx) {
+            typename _Context::template formatter_type<_Tp>{}.format(__ctx);
+          }) {}
+    void (*__format_)(_Context &);
+  } __handle;
+};
+template <class _Args> struct __format_arg_store {
+  __format_arg_store(_Args __args) {
+    (void)__basic_format_arg_value<basic_format_context<char>>{__args};
+  }
+};
+template <class _CharT> struct basic_format_context {
+  template <class _Tp> using formatter_type = formatter<_Tp>;
+  __retarget_buffer<_CharT>::__iterator out();
+};
+void __transform(auto __out_it) {
+  char __transform___first;
+  __out_it.__buffer_->__transform(&__transform___first);
+}
+struct __formatter_integer {
+  template <class _FormatContext> void format(_FormatContext __ctx) {
+    __transform(__ctx.out());
+  }
+};
+template <> struct formatter<int> : __formatter_integer {};
+template <formattable<char> T> void fmt(T);
+void test() {
+  fmt(0);
+  __format_arg_store<int>{0};
+}
+} // namespace GH197597

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

Reply via email to