From 90199e4e4d3f2d7d1c610535567d25221bc2e3b3 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Mon, 24 Nov 2025 12:20:19 +0200 Subject: [PATCH 1/5] [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 struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; template -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 -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 -_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, _Fn>, "bind_back requires decay_t to be constructible from F"); static_assert(is_move_constructible_v>, "bind_back requires decay_t to be move constructible"); static_assert((is_constructible_v, _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 requires is_constructible_v, _Fn> && is_move_constructible_v> && (is_constructible_v, _Args> && ...) && (is_move_constructible_v> && ...) -_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<_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 - _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; template - _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 -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 #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, _Tp, _Up> = true; template <> struct plus { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 { #if _LIBCPP_STD_VER >= 14 template 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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 { template 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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 #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 { template - _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 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t 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 -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 -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 -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper cref(const _Tp& __t) _NOEXCEPT { +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper +cref(const _Tp& __t) _NOEXCEPT { return reference_wrapper(__t); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper 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 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 f; + const std::function cf; + + f.target_type(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + f.target(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cf.target(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + struct ZMT { + void member_function() {}; + }; + // expected-warning@+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@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bind_back([](int a) { return a; }, 94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bind_front([](int a) { return a; }, 94); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bind([](int a) { return a; }, 94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bind([](int a) { return a; }, 94); + + // Reference wrappers + std::reference_wrapper rw{i}; + rw.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::function 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@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::plus()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::plus{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::minus()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::minus{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::multiplies()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::multiplies{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::divides()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::divides{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::modulus()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::modulus{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::negate()(94); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::negate{}(94); +#endif + + // Bitwise operations + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bit_and()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bit_and{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bit_not()(94); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bit_not{}(94); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bit_or()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bit_or{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bit_xor()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bit_xor{}(94, 82); +#endif + + // Comparisons + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::equal_to()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::equal_to{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::not_equal_to()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::not_equal_to{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::less()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::less{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::less_equal()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::less_equal{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::greater_equal()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::greater_equal{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::greater()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::greater{}(94, 82); +#endif + + // Logical operations + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::logical_and()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::logical_and{}(94, 82); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::logical_not()(94); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::logical_not{}(94); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::logical_or()(94, 82); +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::logical_or{}(94, 82); +#endif } From d4df484cc51ee14d995b031bea0d480f486dc453 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Mon, 24 Nov 2025 14:01:52 +0200 Subject: [PATCH 2/5] 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 #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, _Tp, _Up> = true; template <> struct plus { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 { #if _LIBCPP_STD_VER >= 14 template 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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 { template 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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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 #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 { template - [[__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@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::plus()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::plus{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::minus()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::minus{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::multiplies()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::multiplies{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::divides()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::divides{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::modulus()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::modulus{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::negate()(94); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::negate{}(94); -#endif - - // Bitwise operations - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::bit_and()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::bit_and{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::bit_not()(94); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::bit_not{}(94); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::bit_or()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::bit_or{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::bit_xor()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::bit_xor{}(94, 82); -#endif - - // Comparisons - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::equal_to()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::equal_to{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::not_equal_to()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::not_equal_to{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::less()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::less{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::less_equal()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::less_equal{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::greater_equal()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::greater_equal{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::greater()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::greater{}(94, 82); -#endif - - // Logical operations - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::logical_and()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::logical_and{}(94, 82); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::logical_not()(94); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::logical_not{}(94); -#endif - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::logical_or()(94, 82); -#if TEST_STD_VER >= 14 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::logical_or{}(94, 82); -#endif } From 15d5458daac2fa6cf63f87566a19fddf0157d5d3 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Mon, 24 Nov 2025 14:27:10 +0200 Subject: [PATCH 3/5] 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 -[[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 -[[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 -[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper cref(const _Tp& __t) _NOEXCEPT { return reference_wrapper(__t); } template -[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper 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; } From a7bc7287aa01991abba90be902183b9b61bb7b01 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Mon, 24 Nov 2025 15:41:50 +0200 Subject: [PATCH 4/5] Fix CI --- libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp index d07ea7d2e0f5f..282cded05490f 100644 --- a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp @@ -35,7 +35,9 @@ void test() { // Identity +#if TEST_STD_VER >= 20 std::identity{}(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif // Partial function application @@ -51,6 +53,7 @@ void test() { std::bind([](int a) { return a; }, 94); // Reference wrappers + std::reference_wrapper rw{i}; rw.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} std::function vf; From 18c80e89a9bfb44647e07ba2d664bd49ab125e0b Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Mon, 24 Nov 2025 18:38:56 +0200 Subject: [PATCH 5/5] Addressed review comment --- libcxx/include/__functional/reference_wrapper.h | 2 +- libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h index f081b91f2c851..b1efd9f76d877 100644 --- a/libcxx/include/__functional/reference_wrapper.h +++ b/libcxx/include/__functional/reference_wrapper.h @@ -62,7 +62,7 @@ class reference_wrapper : public __weak_result_type<_Tp> { // invoke template - [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t operator()(_ArgTypes&&... __args) const #if _LIBCPP_STD_VER >= 17 // Since is_nothrow_invocable requires C++17 LWG3764 is not backported diff --git a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp index 282cded05490f..898b2ac06e3f2 100644 --- a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp @@ -56,9 +56,6 @@ void test() { std::reference_wrapper rw{i}; rw.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::function 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}}