Skip to content

Commit b37b307

Browse files
authored
[libc++] Applied [[nodiscard]] to some general utilities (#169322)
`[[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 functions/classes have been annotated in this patch: - [x] `bind_back`, `bind_front`, `bind` - [x] `function`, `mem_fn` - [x] `reference_wrapper`
1 parent a7e715a commit b37b307

File tree

8 files changed

+77
-32
lines changed

8 files changed

+77
-32
lines changed

libcxx/include/__functional/bind.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,14 +278,14 @@ template <class _Rp, class _Fp, class... _BoundArgs>
278278
struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
279279

280280
template <class _Fp, class... _BoundArgs>
281-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...>
281+
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...>
282282
bind(_Fp&& __f, _BoundArgs&&... __bound_args) {
283283
typedef __bind<_Fp, _BoundArgs...> type;
284284
return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...);
285285
}
286286

287287
template <class _Rp, class _Fp, class... _BoundArgs>
288-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...>
288+
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...>
289289
bind(_Fp&& __f, _BoundArgs&&... __bound_args) {
290290
typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
291291
return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...);

libcxx/include/__functional/bind_back.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) n
6464

6565
# if _LIBCPP_STD_VER >= 23
6666
template <class _Fn, class... _Args>
67-
_LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
67+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
6868
static_assert(is_constructible_v<decay_t<_Fn>, _Fn>, "bind_back requires decay_t<F> to be constructible from F");
6969
static_assert(is_move_constructible_v<decay_t<_Fn>>, "bind_back requires decay_t<F> to be move constructible");
7070
static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...),

libcxx/include/__functional/bind_front.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> {
4343
template <class _Fn, class... _Args>
4444
requires is_constructible_v<decay_t<_Fn>, _Fn> && is_move_constructible_v<decay_t<_Fn>> &&
4545
(is_constructible_v<decay_t<_Args>, _Args> && ...) && (is_move_constructible_v<decay_t<_Args>> && ...)
46-
_LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
46+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
4747
return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(std::forward<_Fn>(__f), std::forward<_Args>(__args)...);
4848
}
4949

libcxx/include/__functional/function.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -672,11 +672,11 @@ class function<_Rp(_ArgTypes...)>
672672

673673
# if _LIBCPP_HAS_RTTI
674674
// function target access:
675-
_LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
675+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
676676
template <typename _Tp>
677-
_LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
677+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
678678
template <typename _Tp>
679-
_LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
679+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
680680
# endif // _LIBCPP_HAS_RTTI
681681
};
682682

libcxx/include/__functional/mem_fn.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ class __mem_fn : public __weak_result_type<_Tp> {
4343
};
4444

4545
template <class _Rp, class _Tp>
46-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> mem_fn(_Rp _Tp::*__pm) _NOEXCEPT {
46+
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*>
47+
mem_fn(_Rp _Tp::* __pm) _NOEXCEPT {
4748
return __mem_fn<_Rp _Tp::*>(__pm);
4849
}
4950

libcxx/include/__functional/reference_wrapper.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class reference_wrapper : public __weak_result_type<_Tp> {
5858

5959
// access
6060
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT { return *__f_; }
61-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; }
61+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; }
6262

6363
// invoke
6464
template <class... _ArgTypes>
@@ -128,23 +128,25 @@ reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
128128
#endif
129129

130130
template <class _Tp>
131-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
131+
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
132+
_LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
132133
return reference_wrapper<_Tp>(__t);
133134
}
134135

135136
template <class _Tp>
136-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
137+
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
137138
ref(reference_wrapper<_Tp> __t) _NOEXCEPT {
138139
return __t;
139140
}
140141

141142
template <class _Tp>
142-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> cref(const _Tp& __t) _NOEXCEPT {
143+
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
144+
cref(const _Tp& __t) _NOEXCEPT {
143145
return reference_wrapper<const _Tp>(__t);
144146
}
145147

146148
template <class _Tp>
147-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
149+
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
148150
cref(reference_wrapper<_Tp> __t) _NOEXCEPT {
149151
return __t;
150152
}

libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// UNSUPPORTED: c++03, c++11, c++14, c++17
9+
// UNSUPPORTED: c++03
1010

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

@@ -16,5 +16,47 @@
1616

1717
void test() {
1818
int i = 0;
19-
std::identity()(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
19+
20+
// Function wrappers
21+
22+
#if !defined(TEST_HAS_NO_RTTI)
23+
std::function<void(int)> f;
24+
const std::function<void(int)> cf;
25+
26+
f.target_type(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
27+
f.target<void(int)>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
28+
cf.target<void(int)>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
29+
#endif
30+
struct ZMT {
31+
void member_function() {};
32+
};
33+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
34+
std::mem_fn(&ZMT::member_function);
35+
36+
// Identity
37+
38+
#if TEST_STD_VER >= 20
39+
std::identity{}(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
40+
#endif
41+
42+
// Partial function application
43+
44+
#if TEST_STD_VER >= 23
45+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
46+
std::bind_back([](int a) { return a; }, 94);
47+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
48+
std::bind_front([](int a) { return a; }, 94);
49+
#endif
50+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
51+
std::bind([](int a) { return a; }, 94);
52+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
53+
std::bind<float>([](int a) { return a; }, 94);
54+
55+
// Reference wrappers
56+
57+
std::reference_wrapper<int> rw{i};
58+
rw.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
59+
60+
std::ref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
61+
std::cref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
2062
}

libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,23 @@ int main(int, char**)
2727
{
2828
Ptr x = nullptr;
2929
const Ptr cx = nullptr;
30-
std::ref(no_args)();
31-
std::ref(one_arg)(x);
32-
std::ref(one_arg)(cx);
33-
std::ref(two_args)(x, x);
34-
std::ref(two_args)(x, cx);
35-
std::ref(two_args)(cx, x);
36-
std::ref(two_args)(cx, cx);
37-
std::ref(three_args)(x, x, x);
38-
std::ref(three_args)(x, x, cx);
39-
std::ref(three_args)(x, cx, x);
40-
std::ref(three_args)(cx, x, x);
41-
std::ref(three_args)(x, cx, cx);
42-
std::ref(three_args)(cx, x, cx);
43-
std::ref(three_args)(cx, cx, x);
44-
std::ref(three_args)(cx, cx, cx);
45-
std::ref(one_arg_void)(x);
46-
std::ref(one_arg_void)(cx);
30+
(void)std::ref(no_args)();
31+
(void)std::ref(one_arg)(x);
32+
(void)std::ref(one_arg)(cx);
33+
(void)std::ref(two_args)(x, x);
34+
(void)std::ref(two_args)(x, cx);
35+
(void)std::ref(two_args)(cx, x);
36+
(void)std::ref(two_args)(cx, cx);
37+
(void)std::ref(three_args)(x, x, x);
38+
(void)std::ref(three_args)(x, x, cx);
39+
(void)std::ref(three_args)(x, cx, x);
40+
(void)std::ref(three_args)(cx, x, x);
41+
(void)std::ref(three_args)(x, cx, cx);
42+
(void)std::ref(three_args)(cx, x, cx);
43+
(void)std::ref(three_args)(cx, cx, x);
44+
(void)std::ref(three_args)(cx, cx, cx);
45+
(void)std::ref(one_arg_void)(x);
46+
(void)std::ref(one_arg_void)(cx);
4747

4848
return 0;
4949
}

0 commit comments

Comments
 (0)