Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libcxx/include/__functional/bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)...);
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__functional/bind_back.h
Original file line number Diff line number Diff line change
Expand Up @@ -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> && ...),
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__functional/bind_front.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)...);
}

Expand Down
6 changes: 3 additions & 3 deletions libcxx/include/__functional/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down
3 changes: 2 additions & 1 deletion libcxx/include/__functional/mem_fn.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
14 changes: 8 additions & 6 deletions libcxx/include/__functional/reference_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
49 changes: 47 additions & 2 deletions libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: c++03

// check that <functional> functions are marked [[nodiscard]]

Expand All @@ -16,5 +16,50 @@

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@+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<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}}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Loading