llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

<details>
<summary>Changes</summary>

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

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


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+1) 
- (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+1-1) 
- (modified) clang/test/SemaTemplate/concepts-no-early-substitution.cpp (+58) 


``````````diff
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

``````````

</details>


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

Reply via email to