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/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h index 148703b21d84a..b1efd9f76d877 100644 --- a/libcxx/include/__functional/reference_wrapper.h +++ b/libcxx/include/__functional/reference_wrapper.h @@ -58,7 +58,7 @@ 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 @@ -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..898b2ac06e3f2 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,47 @@ 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 + +#if TEST_STD_VER >= 20 + std::identity{}(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + + // 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::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}} } 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; }