https://github.com/awayzjj created 
https://github.com/llvm/llvm-project/pull/232266

Add a reduced, library-independent test for a recursive exception specification 
triggered by std::sort with a reference-wrapped std::function.

Clang 21 incorrectly rejected this code, while current Clang accepts it.

Fixes #53049

>From fbb130b37baabf3a7e08150447efd35b4d53af1d Mon Sep 17 00:00:00 2001
From: awayzjj <[email protected]>
Date: Thu, 15 Oct 2026 08:36:15 +0000
Subject: [PATCH] [clang] Add regression test for GH53049

Add a reduced, library-independent test for a recursive exception
specification triggered by std::sort with a reference-wrapped
std::function.

Clang 21 incorrectly rejected this code, while current Clang accepts it.

Fixes #53049
---
 clang/test/SemaTemplate/GH53049.cpp | 56 +++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 clang/test/SemaTemplate/GH53049.cpp

diff --git a/clang/test/SemaTemplate/GH53049.cpp 
b/clang/test/SemaTemplate/GH53049.cpp
new file mode 100644
index 0000000000000..536a6e0aaf502
--- /dev/null
+++ b/clang/test/SemaTemplate/GH53049.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+// Reduced from libstdc++'s std::sort(..., std::ref(std::function<...>)), which
+// was incorrectly rejected with "exception specification ... uses itself".
+
+template <class T> T &&declval() noexcept;
+template <class T> T &&move(T &t) noexcept { return static_cast<T &&>(t); }
+
+// std::reference_wrapper
+template <class T> class reference_wrapper {
+  static void fun(T &) noexcept;
+  static void fun(T &&) = delete;
+
+public:
+  template <class U, class = decltype(fun(declval<U>()))>
+  reference_wrapper(U &&);
+};
+
+template <class T> reference_wrapper<T> ref(T &t) {
+  return reference_wrapper<T>(t);
+}
+
+// std::function
+template <class Signature> class function {
+public:
+  function();
+  template <class F>
+  function(F &&) noexcept(__is_nothrow_constructible(__remove_cvref(F), F));
+};
+
+// __gnu_cxx::__ops::_Iter_comp_iter
+template <class Compare> struct iter_comp_iter {
+  explicit iter_comp_iter(Compare);
+};
+
+// __gnu_cxx::__ops::_Iter_comp_val
+template <class Compare> struct iter_comp_val {
+  explicit iter_comp_val(Compare);
+  explicit iter_comp_val(const iter_comp_iter<Compare> &);
+  explicit iter_comp_val(iter_comp_iter<Compare> &&);
+};
+
+// __gnu_cxx::__ops::__iter_comp_val
+template <class Compare>
+iter_comp_val<Compare> make_iter_comp_val(iter_comp_iter<Compare>);
+
+// std::__adjust_heap
+template <class Compare> void adjust_heap(iter_comp_iter<Compare> comp) {
+  decltype(make_iter_comp_val(move(comp))) cmp(move(comp));
+}
+
+void test() {
+  function<bool(const int &, const int &)> comp;
+  adjust_heap(iter_comp_iter(ref(comp)));
+}

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

Reply via email to