Skip to content

Commit e208f98

Browse files
committed
[libc++][unordered_multiset] Applied [[nodiscard]]
`[[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/unord.multiset
1 parent f5742c4 commit e208f98

File tree

2 files changed

+152
-37
lines changed

2 files changed

+152
-37
lines changed

libcxx/include/unordered_set

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,20 +1322,20 @@ public:
13221322
_LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(initializer_list<value_type> __il);
13231323
# endif // _LIBCPP_CXX03_LANG
13241324

1325-
_LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
1325+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
13261326
return allocator_type(__table_.__node_alloc());
13271327
}
13281328

13291329
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __table_.size() == 0; }
1330-
_LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1331-
_LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
1330+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1331+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
13321332

1333-
_LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1334-
_LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1335-
_LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1336-
_LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1337-
_LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1338-
_LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
1333+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1334+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1335+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1336+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1337+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1338+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
13391339

13401340
# ifndef _LIBCPP_CXX03_LANG
13411341
template <class... _Args>
@@ -1383,10 +1383,10 @@ public:
13831383
"node_type with incompatible allocator passed to unordered_multiset::insert()");
13841384
return __table_.template __node_handle_insert_multi<node_type>(__hint, std::move(__nh));
13851385
}
1386-
_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __position) {
1386+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __position) {
13871387
return __table_.template __node_handle_extract<node_type>(__position);
13881388
}
1389-
_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1389+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
13901390
return __table_.template __node_handle_extract<node_type>(__key);
13911391
}
13921392

@@ -1427,71 +1427,81 @@ public:
14271427
__table_.swap(__u.__table_);
14281428
}
14291429

1430-
_LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function(); }
1431-
_LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
1430+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function(); }
1431+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
14321432

1433-
_LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1434-
_LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
1433+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1434+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
14351435
# if _LIBCPP_STD_VER >= 20
14361436
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1437-
_LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1437+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
14381438
return __table_.find(__k);
14391439
}
14401440
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1441-
_LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1441+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
14421442
return __table_.find(__k);
14431443
}
14441444
# endif // _LIBCPP_STD_VER >= 20
14451445

1446-
_LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_multi(__k); }
1446+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1447+
return __table_.__count_multi(__k);
1448+
}
14471449
# if _LIBCPP_STD_VER >= 20
14481450
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1449-
_LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1451+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
14501452
return __table_.__count_multi(__k);
14511453
}
14521454
# endif // _LIBCPP_STD_VER >= 20
14531455

14541456
# if _LIBCPP_STD_VER >= 20
1455-
_LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1457+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
14561458

14571459
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1458-
_LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1460+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
14591461
return find(__k) != end();
14601462
}
14611463
# endif // _LIBCPP_STD_VER >= 20
14621464

1463-
_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1465+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
14641466
return __table_.__equal_range_multi(__k);
14651467
}
1466-
_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1468+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
14671469
return __table_.__equal_range_multi(__k);
14681470
}
14691471
# if _LIBCPP_STD_VER >= 20
14701472
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1471-
_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1473+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
14721474
return __table_.__equal_range_multi(__k);
14731475
}
14741476
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1475-
_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1477+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
14761478
return __table_.__equal_range_multi(__k);
14771479
}
14781480
# endif // _LIBCPP_STD_VER >= 20
14791481

1480-
_LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1481-
_LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return __table_.max_bucket_count(); }
1482+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1483+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT {
1484+
return __table_.max_bucket_count();
1485+
}
14821486

1483-
_LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const { return __table_.bucket_size(__n); }
1484-
_LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
1487+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const {
1488+
return __table_.bucket_size(__n);
1489+
}
1490+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
14851491

1486-
_LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1487-
_LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1488-
_LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const { return __table_.cbegin(__n); }
1489-
_LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
1490-
_LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const { return __table_.cbegin(__n); }
1491-
_LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
1492+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1493+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1494+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const {
1495+
return __table_.cbegin(__n);
1496+
}
1497+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
1498+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const {
1499+
return __table_.cbegin(__n);
1500+
}
1501+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
14921502

1493-
_LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
1494-
_LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
1503+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
1504+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
14951505
_LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) { __table_.max_load_factor(__mlf); }
14961506
_LIBCPP_HIDE_FROM_ABI void rehash(size_type __n) { __table_.__rehash_multi(__n); }
14971507
_LIBCPP_HIDE_FROM_ABI void reserve(size_type __n) { __table_.__reserve_multi(__n); }
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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+
// REQUIRES: std-at-least-c++11
10+
11+
// Check that functions are marked [[nodiscard]]
12+
13+
#include <unordered_set>
14+
#include <utility>
15+
16+
#include "test_macros.h"
17+
18+
struct TransparentKey {};
19+
20+
struct StoredKey {
21+
friend bool operator==(StoredKey const&, StoredKey const&) { return true; }
22+
friend bool operator==(StoredKey const&, TransparentKey const&) { return true; }
23+
};
24+
25+
struct TransparentKeyHash {
26+
using is_transparent = void;
27+
28+
constexpr std::size_t operator()(TransparentKey const&) const { return 0; }
29+
constexpr std::size_t operator()(StoredKey const&) const { return 0; }
30+
};
31+
32+
void test() {
33+
std::unordered_multiset<int> us;
34+
const std::unordered_multiset<int> cus;
35+
36+
us.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
37+
38+
us.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
39+
us.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
40+
us.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
41+
42+
us.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
43+
us.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
44+
cus.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
45+
cus.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
46+
cus.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
47+
cus.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
48+
49+
int key = 0;
50+
51+
#if TEST_STD_VER >= 17
52+
us.extract(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
53+
us.extract(us.begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
54+
#endif
55+
56+
us.hash_function(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
57+
us.key_eq(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
58+
59+
us.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
60+
cus.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
61+
#if TEST_STD_VER >= 20
62+
std::unordered_multiset<StoredKey, TransparentKeyHash, std::equal_to<>> tus;
63+
const std::unordered_multiset<StoredKey, TransparentKeyHash, std::equal_to<>> ctus;
64+
65+
TransparentKey tkey;
66+
67+
tus.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
68+
ctus.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
69+
#endif
70+
71+
us.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
72+
#if TEST_STD_VER >= 20
73+
tus.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
74+
#endif
75+
76+
#if TEST_STD_VER >= 20
77+
us.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
78+
tus.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
79+
#endif
80+
81+
us.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
82+
cus.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
83+
#if TEST_STD_VER >= 20
84+
tus.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
85+
ctus.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
86+
#endif
87+
88+
us.bucket_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
89+
us.max_bucket_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
90+
91+
int size = 0;
92+
93+
us.bucket_size(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
94+
us.bucket(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
95+
96+
us.begin(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
97+
us.end(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
98+
cus.begin(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
99+
cus.end(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
100+
cus.cbegin(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
101+
cus.cend(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
102+
103+
us.load_factor(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
104+
us.max_load_factor(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
105+
}

0 commit comments

Comments
 (0)