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
