[libcxx-commits] [libcxx] [libc++] Applied `[[nodiscard]]` to some general utilities (PR #169322)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Mon Nov 24 04:27:26 PST 2025


https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/169322

>From 90199e4e4d3f2d7d1c610535567d25221bc2e3b3 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 24 Nov 2025 12:20:19 +0200
Subject: [PATCH 1/3] [libc++] Applied `[[nodiscard]]` to some general
 utilities

`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html#apply-nodiscard-where-relevant

The following has been annotated in this patch:
- [x] `bind_back`, `bind_front`, `bind`
- [x] `function`, `mem_fn`
- [x] `reference_wrapper`
---
 libcxx/include/__functional/bind.h            |   4 +-
 libcxx/include/__functional/bind_back.h       |   2 +-
 libcxx/include/__functional/bind_front.h      |   2 +-
 libcxx/include/__functional/function.h        |   6 +-
 libcxx/include/__functional/mem_fn.h          |   3 +-
 libcxx/include/__functional/operations.h      | 105 ++++++-----
 .../include/__functional/reference_wrapper.h  |  14 +-
 .../functional.nodiscard.verify.cpp           | 174 +++++++++++++++++-
 8 files changed, 252 insertions(+), 58 deletions(-)

diff --git a/libcxx/include/__functional/bind.h b/libcxx/include/__functional/bind.h
index def9e4c4ec7a9..328dc3bf3dabc 100644
--- a/libcxx/include/__functional/bind.h
+++ b/libcxx/include/__functional/bind.h
@@ -278,14 +278,14 @@ template <class _Rp, class _Fp, class... _BoundArgs>
 struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
 
 template <class _Fp, class... _BoundArgs>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...>
 bind(_Fp&& __f, _BoundArgs&&... __bound_args) {
   typedef __bind<_Fp, _BoundArgs...> type;
   return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...);
 }
 
 template <class _Rp, class _Fp, class... _BoundArgs>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...>
 bind(_Fp&& __f, _BoundArgs&&... __bound_args) {
   typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
   return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...);
diff --git a/libcxx/include/__functional/bind_back.h b/libcxx/include/__functional/bind_back.h
index e44768d2283c0..41177144d81fe 100644
--- a/libcxx/include/__functional/bind_back.h
+++ b/libcxx/include/__functional/bind_back.h
@@ -64,7 +64,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) n
 
 #  if _LIBCPP_STD_VER >= 23
 template <class _Fn, class... _Args>
-_LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
   static_assert(is_constructible_v<decay_t<_Fn>, _Fn>, "bind_back requires decay_t<F> to be constructible from F");
   static_assert(is_move_constructible_v<decay_t<_Fn>>, "bind_back requires decay_t<F> to be move constructible");
   static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...),
diff --git a/libcxx/include/__functional/bind_front.h b/libcxx/include/__functional/bind_front.h
index 87ef3affe80b6..427accf96339d 100644
--- a/libcxx/include/__functional/bind_front.h
+++ b/libcxx/include/__functional/bind_front.h
@@ -43,7 +43,7 @@ struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> {
 template <class _Fn, class... _Args>
   requires is_constructible_v<decay_t<_Fn>, _Fn> && is_move_constructible_v<decay_t<_Fn>> &&
            (is_constructible_v<decay_t<_Args>, _Args> && ...) && (is_move_constructible_v<decay_t<_Args>> && ...)
-_LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
   return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(std::forward<_Fn>(__f), std::forward<_Args>(__args)...);
 }
 
diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h
index c768fd90d01b4..121417f90ff01 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -672,11 +672,11 @@ class function<_Rp(_ArgTypes...)>
 
 #  if _LIBCPP_HAS_RTTI
   // function target access:
-  _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
   template <typename _Tp>
-  _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
   template <typename _Tp>
-  _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
 #  endif // _LIBCPP_HAS_RTTI
 };
 
diff --git a/libcxx/include/__functional/mem_fn.h b/libcxx/include/__functional/mem_fn.h
index 690393988c5a5..1c9340c4f4183 100644
--- a/libcxx/include/__functional/mem_fn.h
+++ b/libcxx/include/__functional/mem_fn.h
@@ -43,7 +43,8 @@ class __mem_fn : public __weak_result_type<_Tp> {
 };
 
 template <class _Rp, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> mem_fn(_Rp _Tp::*__pm) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*>
+mem_fn(_Rp _Tp::* __pm) _NOEXCEPT {
   return __mem_fn<_Rp _Tp::*>(__pm);
 }
 
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index 7f315ca851c08..ff4cc08f43052 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -35,7 +35,8 @@ template <class _Tp>
 #endif
 struct plus : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x + __y;
   }
 };
@@ -53,7 +54,7 @@ inline const bool __desugars_to_v<__plus_tag, plus<void>, _Tp, _Up> = true;
 template <>
 struct plus<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) + std::forward<_T2>(__u);
@@ -69,7 +70,8 @@ template <class _Tp>
 #endif
 struct minus : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x - __y;
   }
 };
@@ -79,7 +81,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus);
 template <>
 struct minus<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) - std::forward<_T2>(__u);
@@ -95,7 +97,8 @@ template <class _Tp>
 #endif
 struct multiplies : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x * __y;
   }
 };
@@ -105,7 +108,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies);
 template <>
 struct multiplies<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) * std::forward<_T2>(__u);
@@ -121,7 +124,8 @@ template <class _Tp>
 #endif
 struct divides : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x / __y;
   }
 };
@@ -131,7 +135,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides);
 template <>
 struct divides<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) / std::forward<_T2>(__u);
@@ -147,7 +151,8 @@ template <class _Tp>
 #endif
 struct modulus : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x % __y;
   }
 };
@@ -157,7 +162,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus);
 template <>
 struct modulus<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) % std::forward<_T2>(__u);
@@ -173,7 +178,9 @@ template <class _Tp>
 #endif
 struct negate : __unary_function<_Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const {
+    return -__x;
+  }
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
 
@@ -181,7 +188,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
 template <>
 struct negate<void> {
   template <class _Tp>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
       noexcept(noexcept(-std::forward<_Tp>(__x))) //
       -> decltype(-std::forward<_Tp>(__x)) {
     return -std::forward<_Tp>(__x);
@@ -199,7 +206,8 @@ template <class _Tp>
 #endif
 struct bit_and : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x & __y;
   }
 };
@@ -209,9 +217,9 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and);
 template <>
 struct bit_and<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) &
-                        std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+      noexcept(noexcept(std::forward<_T1>(__t) & std::forward<_T2>(__u)))
+          -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) & std::forward<_T2>(__u);
   }
   typedef void is_transparent;
@@ -221,14 +229,16 @@ struct bit_and<void> {
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 struct bit_not : __unary_function<_Tp, _Tp> {
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return ~__x; }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const {
+    return ~__x;
+  }
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not);
 
 template <>
 struct bit_not<void> {
   template <class _Tp>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
       noexcept(noexcept(~std::forward<_Tp>(__x))) //
       -> decltype(~std::forward<_Tp>(__x)) {
     return ~std::forward<_Tp>(__x);
@@ -244,7 +254,8 @@ template <class _Tp>
 #endif
 struct bit_or : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x | __y;
   }
 };
@@ -254,7 +265,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or);
 template <>
 struct bit_or<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) | std::forward<_T2>(__u);
@@ -270,7 +281,8 @@ template <class _Tp>
 #endif
 struct bit_xor : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x ^ __y;
   }
 };
@@ -280,7 +292,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor);
 template <>
 struct bit_xor<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) ^ std::forward<_T2>(__u);
@@ -298,7 +310,8 @@ template <class _Tp>
 #endif
 struct equal_to : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x == __y;
   }
 };
@@ -308,7 +321,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to);
 template <>
 struct equal_to<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) == std::forward<_T2>(__u);
@@ -333,7 +346,7 @@ template <class _Tp>
 #endif
 struct not_equal_to : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x != __y;
   }
 };
@@ -343,7 +356,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to);
 template <>
 struct not_equal_to<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) != std::forward<_T2>(__u);
@@ -355,7 +368,8 @@ struct not_equal_to<void> {
 template <class _Tp>
 struct less : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x < __y;
   }
 };
@@ -371,7 +385,7 @@ inline const bool __desugars_to_v<__totally_ordered_less_tag, less<_Tp>, _Tp, _T
 template <>
 struct less<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) < std::forward<_T2>(__u);
@@ -401,7 +415,8 @@ template <class _Tp>
 #endif
 struct less_equal : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x <= __y;
   }
 };
@@ -411,7 +426,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal);
 template <>
 struct less_equal<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) <= std::forward<_T2>(__u);
@@ -427,7 +442,8 @@ template <class _Tp>
 #endif
 struct greater_equal : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x >= __y;
   }
 };
@@ -437,9 +453,9 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal);
 template <>
 struct greater_equal<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) >=
-                        std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+      noexcept(noexcept(std::forward<_T1>(__t) >= std::forward<_T2>(__u)))
+          -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) >= std::forward<_T2>(__u);
   }
   typedef void is_transparent;
@@ -453,7 +469,8 @@ template <class _Tp>
 #endif
 struct greater : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x > __y;
   }
 };
@@ -466,7 +483,7 @@ inline const bool __desugars_to_v<__greater_tag, greater<_Tp>, _Tp, _Tp> = true;
 template <>
 struct greater<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) > std::forward<_T2>(__u);
@@ -495,7 +512,8 @@ template <class _Tp>
 #endif
 struct logical_and : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x && __y;
   }
 };
@@ -505,7 +523,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and);
 template <>
 struct logical_and<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) && std::forward<_T2>(__u);
@@ -521,7 +539,9 @@ template <class _Tp>
 #endif
 struct logical_not : __unary_function<_Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; }
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const {
+    return !__x;
+  }
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
 
@@ -529,7 +549,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
 template <>
 struct logical_not<void> {
   template <class _Tp>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
       noexcept(noexcept(!std::forward<_Tp>(__x))) //
       -> decltype(!std::forward<_Tp>(__x)) {
     return !std::forward<_Tp>(__x);
@@ -545,7 +565,8 @@ template <class _Tp>
 #endif
 struct logical_or : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
+  operator()(const _Tp& __x, const _Tp& __y) const {
     return __x || __y;
   }
 };
@@ -555,7 +576,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or);
 template <>
 struct logical_or<void> {
   template <class _T1, class _T2>
-  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) || std::forward<_T2>(__u);
diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index 148703b21d84a..1bb33cb033dcb 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -58,11 +58,11 @@ class reference_wrapper : public __weak_result_type<_Tp> {
 
   // access
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT { return *__f_; }
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; }
 
   // invoke
   template <class... _ArgTypes>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<type&, _ArgTypes...>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<type&, _ArgTypes...>
   operator()(_ArgTypes&&... __args) const
 #if _LIBCPP_STD_VER >= 17
       // Since is_nothrow_invocable requires C++17 LWG3764 is not backported
@@ -128,23 +128,25 @@ reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
 #endif
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
   return reference_wrapper<_Tp>(__t);
 }
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
 ref(reference_wrapper<_Tp> __t) _NOEXCEPT {
   return __t;
 }
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> cref(const _Tp& __t) _NOEXCEPT {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
+cref(const _Tp& __t) _NOEXCEPT {
   return reference_wrapper<const _Tp>(__t);
 }
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
 cref(reference_wrapper<_Tp> __t) _NOEXCEPT {
   return __t;
 }
diff --git a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
index 4307976e9e442..08017aa5573fb 100644
--- a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++03
 
 // check that <functional> functions are marked [[nodiscard]]
 
@@ -16,5 +16,175 @@
 
 void test() {
   int i = 0;
-  std::identity()(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  // Function wrappers
+
+#if !defined(TEST_HAS_NO_RTTI)
+  std::function<void(int)> f;
+  const std::function<void(int)> cf;
+
+  f.target_type();        // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  f.target<void(int)>();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cf.target<void(int)>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+  struct ZMT {
+    void member_function() {};
+  };
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::mem_fn(&ZMT::member_function);
+
+  // Identity
+
+  std::identity{}(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  // Partial function application
+
+#if TEST_STD_VER >= 23
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bind_back([](int a) { return a; }, 94);
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bind_front([](int a) { return a; }, 94);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bind([](int a) { return a; }, 94);
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bind<float>([](int a) { return a; }, 94);
+
+  // Reference wrappers
+  std::reference_wrapper<int> rw{i};
+  rw.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::function<int(int)> vf;
+  auto rwf = std::ref(vf);
+  rwf(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  std::ref(i);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::cref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  // Operator function objects
+
+  // Arithmetic
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::plus<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::plus<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::minus<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::minus<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::multiplies<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::multiplies<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::divides<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::divides<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::modulus<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::modulus<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::negate<int>()(94);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::negate<void>{}(94);
+#endif
+
+  // Bitwise operations
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bit_and<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bit_and<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bit_not<int>()(94);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bit_not<void>{}(94);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bit_or<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bit_or<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bit_xor<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::bit_xor<void>{}(94, 82);
+#endif
+
+  // Comparisons
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::equal_to<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::equal_to<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::not_equal_to<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::not_equal_to<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::less<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::less<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::less_equal<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::less_equal<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::greater_equal<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::greater_equal<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::greater<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::greater<void>{}(94, 82);
+#endif
+
+  // Logical operations
+
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::logical_and<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::logical_and<void>{}(94, 82);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::logical_not<int>()(94);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::logical_not<void>{}(94);
+#endif
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::logical_or<int>()(94, 82);
+#if TEST_STD_VER >= 14
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::logical_or<void>{}(94, 82);
+#endif
 }

>From d4df484cc51ee14d995b031bea0d480f486dc453 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 24 Nov 2025 14:01:52 +0200
Subject: [PATCH 2/3] Revert some changes

---
 libcxx/include/__functional/operations.h      | 105 ++++++--------
 .../functional.nodiscard.verify.cpp           | 128 ------------------
 2 files changed, 42 insertions(+), 191 deletions(-)

diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index ff4cc08f43052..7f315ca851c08 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -35,8 +35,7 @@ template <class _Tp>
 #endif
 struct plus : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
     return __x + __y;
   }
 };
@@ -54,7 +53,7 @@ inline const bool __desugars_to_v<__plus_tag, plus<void>, _Tp, _Up> = true;
 template <>
 struct plus<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) + std::forward<_T2>(__u);
@@ -70,8 +69,7 @@ template <class _Tp>
 #endif
 struct minus : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
     return __x - __y;
   }
 };
@@ -81,7 +79,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus);
 template <>
 struct minus<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) - std::forward<_T2>(__u);
@@ -97,8 +95,7 @@ template <class _Tp>
 #endif
 struct multiplies : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
     return __x * __y;
   }
 };
@@ -108,7 +105,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies);
 template <>
 struct multiplies<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) * std::forward<_T2>(__u);
@@ -124,8 +121,7 @@ template <class _Tp>
 #endif
 struct divides : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
     return __x / __y;
   }
 };
@@ -135,7 +131,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides);
 template <>
 struct divides<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) / std::forward<_T2>(__u);
@@ -151,8 +147,7 @@ template <class _Tp>
 #endif
 struct modulus : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
     return __x % __y;
   }
 };
@@ -162,7 +157,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus);
 template <>
 struct modulus<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) % std::forward<_T2>(__u);
@@ -178,9 +173,7 @@ template <class _Tp>
 #endif
 struct negate : __unary_function<_Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const {
-    return -__x;
-  }
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; }
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
 
@@ -188,7 +181,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
 template <>
 struct negate<void> {
   template <class _Tp>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
       noexcept(noexcept(-std::forward<_Tp>(__x))) //
       -> decltype(-std::forward<_Tp>(__x)) {
     return -std::forward<_Tp>(__x);
@@ -206,8 +199,7 @@ template <class _Tp>
 #endif
 struct bit_and : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
     return __x & __y;
   }
 };
@@ -217,9 +209,9 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and);
 template <>
 struct bit_and<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) & std::forward<_T2>(__u)))
-          -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+      noexcept(noexcept(std::forward<_T1>(__t) &
+                        std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) & std::forward<_T2>(__u);
   }
   typedef void is_transparent;
@@ -229,16 +221,14 @@ struct bit_and<void> {
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp = void>
 struct bit_not : __unary_function<_Tp, _Tp> {
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const {
-    return ~__x;
-  }
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return ~__x; }
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not);
 
 template <>
 struct bit_not<void> {
   template <class _Tp>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
       noexcept(noexcept(~std::forward<_Tp>(__x))) //
       -> decltype(~std::forward<_Tp>(__x)) {
     return ~std::forward<_Tp>(__x);
@@ -254,8 +244,7 @@ template <class _Tp>
 #endif
 struct bit_or : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
     return __x | __y;
   }
 };
@@ -265,7 +254,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or);
 template <>
 struct bit_or<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) | std::forward<_T2>(__u);
@@ -281,8 +270,7 @@ template <class _Tp>
 #endif
 struct bit_xor : __binary_function<_Tp, _Tp, _Tp> {
   typedef _Tp __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
     return __x ^ __y;
   }
 };
@@ -292,7 +280,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor);
 template <>
 struct bit_xor<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) ^ std::forward<_T2>(__u);
@@ -310,8 +298,7 @@ template <class _Tp>
 #endif
 struct equal_to : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x == __y;
   }
 };
@@ -321,7 +308,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to);
 template <>
 struct equal_to<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) == std::forward<_T2>(__u);
@@ -346,7 +333,7 @@ template <class _Tp>
 #endif
 struct not_equal_to : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x != __y;
   }
 };
@@ -356,7 +343,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to);
 template <>
 struct not_equal_to<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) != std::forward<_T2>(__u);
@@ -368,8 +355,7 @@ struct not_equal_to<void> {
 template <class _Tp>
 struct less : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x < __y;
   }
 };
@@ -385,7 +371,7 @@ inline const bool __desugars_to_v<__totally_ordered_less_tag, less<_Tp>, _Tp, _T
 template <>
 struct less<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) < std::forward<_T2>(__u);
@@ -415,8 +401,7 @@ template <class _Tp>
 #endif
 struct less_equal : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x <= __y;
   }
 };
@@ -426,7 +411,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal);
 template <>
 struct less_equal<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) <= std::forward<_T2>(__u);
@@ -442,8 +427,7 @@ template <class _Tp>
 #endif
 struct greater_equal : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x >= __y;
   }
 };
@@ -453,9 +437,9 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal);
 template <>
 struct greater_equal<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) >= std::forward<_T2>(__u)))
-          -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+      noexcept(noexcept(std::forward<_T1>(__t) >=
+                        std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) >= std::forward<_T2>(__u);
   }
   typedef void is_transparent;
@@ -469,8 +453,7 @@ template <class _Tp>
 #endif
 struct greater : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x > __y;
   }
 };
@@ -483,7 +466,7 @@ inline const bool __desugars_to_v<__greater_tag, greater<_Tp>, _Tp, _Tp> = true;
 template <>
 struct greater<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) > std::forward<_T2>(__u);
@@ -512,8 +495,7 @@ template <class _Tp>
 #endif
 struct logical_and : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x && __y;
   }
 };
@@ -523,7 +505,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and);
 template <>
 struct logical_and<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) && std::forward<_T2>(__u);
@@ -539,9 +521,7 @@ template <class _Tp>
 #endif
 struct logical_not : __unary_function<_Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const {
-    return !__x;
-  }
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; }
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
 
@@ -549,7 +529,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
 template <>
 struct logical_not<void> {
   template <class _Tp>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
       noexcept(noexcept(!std::forward<_Tp>(__x))) //
       -> decltype(!std::forward<_Tp>(__x)) {
     return !std::forward<_Tp>(__x);
@@ -565,8 +545,7 @@ template <class _Tp>
 #endif
 struct logical_or : __binary_function<_Tp, _Tp, bool> {
   typedef bool __result_type; // used by valarray
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
-  operator()(const _Tp& __x, const _Tp& __y) const {
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
     return __x || __y;
   }
 };
@@ -576,7 +555,7 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or);
 template <>
 struct logical_or<void> {
   template <class _T1, class _T2>
-  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
       noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) //
       -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) || std::forward<_T2>(__u);
diff --git a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
index 08017aa5573fb..d07ea7d2e0f5f 100644
--- a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
@@ -59,132 +59,4 @@ void test() {
 
   std::ref(i);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   std::cref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-
-  // Operator function objects
-
-  // Arithmetic
-
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::plus<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::plus<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::minus<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::minus<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::multiplies<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::multiplies<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::divides<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::divides<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::modulus<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::modulus<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::negate<int>()(94);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::negate<void>{}(94);
-#endif
-
-  // Bitwise operations
-
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::bit_and<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::bit_and<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::bit_not<int>()(94);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::bit_not<void>{}(94);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::bit_or<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::bit_or<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::bit_xor<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::bit_xor<void>{}(94, 82);
-#endif
-
-  // Comparisons
-
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::equal_to<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::equal_to<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::not_equal_to<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::not_equal_to<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::less<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::less<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::less_equal<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::less_equal<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::greater_equal<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::greater_equal<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::greater<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::greater<void>{}(94, 82);
-#endif
-
-  // Logical operations
-
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::logical_and<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::logical_and<void>{}(94, 82);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::logical_not<int>()(94);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::logical_not<void>{}(94);
-#endif
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::logical_or<int>()(94, 82);
-#if TEST_STD_VER >= 14
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::logical_or<void>{}(94, 82);
-#endif
 }

>From 15d5458daac2fa6cf63f87566a19fddf0157d5d3 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 24 Nov 2025 14:27:10 +0200
Subject: [PATCH 3/3] Fixed issues

---
 .../include/__functional/reference_wrapper.h  |  8 ++---
 .../robust_against_adl.pass.cpp               | 34 +++++++++----------
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index 1bb33cb033dcb..f081b91f2c851 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -128,25 +128,25 @@ reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
 #endif
 
 template <class _Tp>
-[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
 _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
   return reference_wrapper<_Tp>(__t);
 }
 
 template <class _Tp>
-[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
 ref(reference_wrapper<_Tp> __t) _NOEXCEPT {
   return __t;
 }
 
 template <class _Tp>
-[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
 cref(const _Tp& __t) _NOEXCEPT {
   return reference_wrapper<const _Tp>(__t);
 }
 
 template <class _Tp>
-[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
 cref(reference_wrapper<_Tp> __t) _NOEXCEPT {
   return __t;
 }
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp
index 2774401b052b8..f666e8bc31a65 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp
@@ -27,23 +27,23 @@ int main(int, char**)
 {
     Ptr x = nullptr;
     const Ptr cx = nullptr;
-    std::ref(no_args)();
-    std::ref(one_arg)(x);
-    std::ref(one_arg)(cx);
-    std::ref(two_args)(x, x);
-    std::ref(two_args)(x, cx);
-    std::ref(two_args)(cx, x);
-    std::ref(two_args)(cx, cx);
-    std::ref(three_args)(x, x, x);
-    std::ref(three_args)(x, x, cx);
-    std::ref(three_args)(x, cx, x);
-    std::ref(three_args)(cx, x, x);
-    std::ref(three_args)(x, cx, cx);
-    std::ref(three_args)(cx, x, cx);
-    std::ref(three_args)(cx, cx, x);
-    std::ref(three_args)(cx, cx, cx);
-    std::ref(one_arg_void)(x);
-    std::ref(one_arg_void)(cx);
+    (void)std::ref(no_args)();
+    (void)std::ref(one_arg)(x);
+    (void)std::ref(one_arg)(cx);
+    (void)std::ref(two_args)(x, x);
+    (void)std::ref(two_args)(x, cx);
+    (void)std::ref(two_args)(cx, x);
+    (void)std::ref(two_args)(cx, cx);
+    (void)std::ref(three_args)(x, x, x);
+    (void)std::ref(three_args)(x, x, cx);
+    (void)std::ref(three_args)(x, cx, x);
+    (void)std::ref(three_args)(cx, x, x);
+    (void)std::ref(three_args)(x, cx, cx);
+    (void)std::ref(three_args)(cx, x, cx);
+    (void)std::ref(three_args)(cx, cx, x);
+    (void)std::ref(three_args)(cx, cx, cx);
+    (void)std::ref(one_arg_void)(x);
+    (void)std::ref(one_arg_void)(cx);
 
     return 0;
 }



More information about the libcxx-commits mailing list