Skip to content

Commit 3e2a8e2

Browse files
authored
[libc++][multiset] Applied [[nodiscard]] (#171654)
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue. - https://libcxx.llvm.org/CodingGuidelines.htm - https://wg21.link/multiset
1 parent 5bc7b9d commit 3e2a8e2

File tree

2 files changed

+156
-39
lines changed

2 files changed

+156
-39
lines changed

libcxx/include/set

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,24 +1180,28 @@ public:
11801180
static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), "");
11811181
}
11821182

1183-
_LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1184-
_LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1185-
_LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1186-
_LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
1183+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1184+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1185+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1186+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
11871187

1188-
_LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1189-
_LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1190-
_LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1191-
_LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
1188+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1189+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
1190+
return const_reverse_iterator(end());
1191+
}
1192+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1193+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
1194+
return const_reverse_iterator(begin());
1195+
}
11921196

1193-
_LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1194-
_LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1195-
_LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1196-
_LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
1197+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1198+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1199+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1200+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
11971201

11981202
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
1199-
_LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1200-
_LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
1203+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1204+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
12011205

12021206
// modifiers:
12031207
# ifndef _LIBCPP_CXX03_LANG
@@ -1254,10 +1258,10 @@ public:
12541258
"node_type with incompatible allocator passed to multiset::insert()");
12551259
return __tree_.template __node_handle_insert_multi<node_type>(__hint, std::move(__nh));
12561260
}
1257-
_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1261+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
12581262
return __tree_.template __node_handle_extract<node_type>(__key);
12591263
}
1260-
_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1264+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
12611265
return __tree_.template __node_handle_extract<node_type>(__it);
12621266
}
12631267
template <class _Compare2>
@@ -1290,88 +1294,94 @@ public:
12901294
__tree_.swap(__s.__tree_);
12911295
}
12921296

1293-
_LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
1294-
_LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
1295-
_LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
1297+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
1298+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
1299+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
12961300

12971301
// set operations:
1298-
_LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1299-
_LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
1302+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1303+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
13001304
# if _LIBCPP_STD_VER >= 14
13011305
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1302-
_LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1306+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
13031307
return __tree_.find(__k);
13041308
}
13051309
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1306-
_LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1310+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
13071311
return __tree_.find(__k);
13081312
}
13091313
# endif
13101314

1311-
_LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_multi(__k); }
1315+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1316+
return __tree_.__count_multi(__k);
1317+
}
13121318
# if _LIBCPP_STD_VER >= 14
13131319
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1314-
_LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1320+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
13151321
return __tree_.__count_multi(__k);
13161322
}
13171323
# endif
13181324

13191325
# if _LIBCPP_STD_VER >= 20
1320-
_LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1326+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
13211327
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1322-
_LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1328+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
13231329
return find(__k) != end();
13241330
}
13251331
# endif // _LIBCPP_STD_VER >= 20
13261332

1327-
_LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.__lower_bound_multi(__k); }
1333+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) {
1334+
return __tree_.__lower_bound_multi(__k);
1335+
}
13281336

1329-
_LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
1337+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
13301338
return __tree_.__lower_bound_multi(__k);
13311339
}
13321340

13331341
# if _LIBCPP_STD_VER >= 14
13341342
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1335-
_LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1343+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
13361344
return __tree_.__lower_bound_multi(__k);
13371345
}
13381346

13391347
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1340-
_LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1348+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
13411349
return __tree_.__lower_bound_multi(__k);
13421350
}
13431351
# endif
13441352

1345-
_LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.__upper_bound_multi(__k); }
1353+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) {
1354+
return __tree_.__upper_bound_multi(__k);
1355+
}
13461356

1347-
_LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
1357+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
13481358
return __tree_.__upper_bound_multi(__k);
13491359
}
13501360

13511361
# if _LIBCPP_STD_VER >= 14
13521362
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1353-
_LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1363+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
13541364
return __tree_.__upper_bound_multi(__k);
13551365
}
13561366
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1357-
_LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1367+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
13581368
return __tree_.__upper_bound_multi(__k);
13591369
}
13601370
# endif
13611371

1362-
_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1372+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
13631373
return __tree_.__equal_range_multi(__k);
13641374
}
1365-
_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1375+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
13661376
return __tree_.__equal_range_multi(__k);
13671377
}
13681378
# if _LIBCPP_STD_VER >= 14
13691379
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1370-
_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1380+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
13711381
return __tree_.__equal_range_multi(__k);
13721382
}
13731383
template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1374-
_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1384+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
13751385
return __tree_.__equal_range_multi(__k);
13761386
}
13771387
# endif
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// Check that functions are marked [[nodiscard]]
10+
11+
#include <set>
12+
13+
#include "test_macros.h"
14+
15+
#if TEST_STD_VER >= 14
16+
struct TransparentKey {
17+
explicit operator int() const;
18+
};
19+
20+
struct TransparentCompare {
21+
using is_transparent = void; // This makes the comparator transparent
22+
23+
bool operator()(const int&, const TransparentKey&) const;
24+
25+
bool operator()(const TransparentKey&, const int&) const;
26+
27+
bool operator()(const int&, const int&) const;
28+
};
29+
#endif
30+
31+
void test() {
32+
std::multiset<int> s;
33+
const std::multiset<int> cs;
34+
35+
s.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
36+
cs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
37+
s.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
38+
cs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
39+
40+
s.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
41+
cs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
42+
s.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
43+
cs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
44+
45+
cs.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
46+
cs.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
47+
cs.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
48+
cs.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
49+
50+
s.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
51+
s.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
52+
s.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
53+
54+
int key = 0;
55+
56+
#if TEST_STD_VER >= 17
57+
s.extract(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
58+
s.extract(s.begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
59+
#endif
60+
61+
s.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
62+
s.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
63+
s.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
64+
65+
s.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
66+
cs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
67+
#if TEST_STD_VER >= 14
68+
std::multiset<int, TransparentCompare> ts;
69+
const std::multiset<int, TransparentCompare> cts{};
70+
71+
TransparentKey tkey;
72+
73+
ts.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
74+
cts.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
75+
#endif
76+
77+
s.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
78+
#if TEST_STD_VER >= 14
79+
ts.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
80+
#endif
81+
82+
#if TEST_STD_VER >= 20
83+
s.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
84+
ts.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
85+
#endif
86+
87+
s.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
88+
cs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
89+
#if TEST_STD_VER >= 14
90+
ts.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
91+
cts.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
92+
#endif
93+
94+
s.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
95+
cs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
96+
#if TEST_STD_VER >= 14
97+
ts.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
98+
cts.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
99+
#endif
100+
101+
s.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
102+
cs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
103+
#if TEST_STD_VER >= 14
104+
ts.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
105+
cts.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
106+
#endif
107+
}

0 commit comments

Comments
 (0)