Skip to content

Commit 7b230dc

Browse files
committed
[llibc++][unordered_multimap] 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.multimap
1 parent f5742c4 commit 7b230dc

File tree

2 files changed

+152
-37
lines changed

2 files changed

+152
-37
lines changed

libcxx/include/unordered_map

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,20 +1798,20 @@ public:
17981798
_LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(initializer_list<value_type> __il);
17991799
# endif // _LIBCPP_CXX03_LANG
18001800

1801-
_LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
1801+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
18021802
return allocator_type(__table_.__node_alloc());
18031803
}
18041804

18051805
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __table_.size() == 0; }
1806-
_LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1807-
_LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
1806+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1807+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
18081808

1809-
_LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1810-
_LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1811-
_LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1812-
_LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1813-
_LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1814-
_LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
1809+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1810+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1811+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1812+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1813+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1814+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
18151815

18161816
_LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return __table_.__emplace_multi(__x); }
18171817

@@ -1879,10 +1879,10 @@ public:
18791879
"node_type with incompatible allocator passed to unordered_multimap::insert()");
18801880
return __table_.template __node_handle_insert_multi<node_type>(__hint.__i_, std::move(__nh));
18811881
}
1882-
_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1882+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
18831883
return __table_.template __node_handle_extract<node_type>(__key);
18841884
}
1885-
_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1885+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
18861886
return __table_.template __node_handle_extract<node_type>(__it.__i_);
18871887
}
18881888

@@ -1916,71 +1916,83 @@ public:
19161916
__table_.swap(__u.__table_);
19171917
}
19181918

1919-
_LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function().hash_function(); }
1920-
_LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); }
1919+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI hasher hash_function() const {
1920+
return __table_.hash_function().hash_function();
1921+
}
1922+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); }
19211923

1922-
_LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1923-
_LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
1924+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1925+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
19241926
# if _LIBCPP_STD_VER >= 20
19251927
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1926-
_LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1928+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
19271929
return __table_.find(__k);
19281930
}
19291931
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1930-
_LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1932+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
19311933
return __table_.find(__k);
19321934
}
19331935
# endif // _LIBCPP_STD_VER >= 20
19341936

1935-
_LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_multi(__k); }
1937+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1938+
return __table_.__count_multi(__k);
1939+
}
19361940
# if _LIBCPP_STD_VER >= 20
19371941
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1938-
_LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1942+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
19391943
return __table_.__count_multi(__k);
19401944
}
19411945
# endif // _LIBCPP_STD_VER >= 20
19421946

19431947
# if _LIBCPP_STD_VER >= 20
1944-
_LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1948+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
19451949

19461950
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1947-
_LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1951+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
19481952
return find(__k) != end();
19491953
}
19501954
# endif // _LIBCPP_STD_VER >= 20
19511955

1952-
_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1956+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
19531957
return __table_.__equal_range_multi(__k);
19541958
}
1955-
_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1959+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
19561960
return __table_.__equal_range_multi(__k);
19571961
}
19581962
# if _LIBCPP_STD_VER >= 20
19591963
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1960-
_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1964+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
19611965
return __table_.__equal_range_multi(__k);
19621966
}
19631967
template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1964-
_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1968+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
19651969
return __table_.__equal_range_multi(__k);
19661970
}
19671971
# endif // _LIBCPP_STD_VER >= 20
19681972

1969-
_LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1970-
_LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return __table_.max_bucket_count(); }
1973+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1974+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT {
1975+
return __table_.max_bucket_count();
1976+
}
19711977

1972-
_LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const { return __table_.bucket_size(__n); }
1973-
_LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
1978+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const {
1979+
return __table_.bucket_size(__n);
1980+
}
1981+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
19741982

1975-
_LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1976-
_LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1977-
_LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const { return __table_.cbegin(__n); }
1978-
_LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
1979-
_LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const { return __table_.cbegin(__n); }
1980-
_LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
1983+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1984+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1985+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const {
1986+
return __table_.cbegin(__n);
1987+
}
1988+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
1989+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const {
1990+
return __table_.cbegin(__n);
1991+
}
1992+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
19811993

1982-
_LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
1983-
_LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
1994+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
1995+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
19841996
_LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) { __table_.max_load_factor(__mlf); }
19851997
_LIBCPP_HIDE_FROM_ABI void rehash(size_type __n) { __table_.__rehash_multi(__n); }
19861998
_LIBCPP_HIDE_FROM_ABI void reserve(size_type __n) { __table_.__reserve_multi(__n); }
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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_map>
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_multimap<int, int> m;
34+
const std::unordered_multimap<int, int> cm;
35+
36+
m.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
37+
38+
m.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
39+
m.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
40+
m.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
41+
42+
m.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
43+
m.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
44+
cm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
45+
cm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
46+
cm.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
47+
cm.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+
m.extract(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
53+
m.extract(m.begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
54+
#endif
55+
56+
m.hash_function(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
57+
m.key_eq(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
58+
59+
m.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
60+
cm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
61+
#if TEST_STD_VER >= 20
62+
std::unordered_multimap<StoredKey, int, TransparentKeyHash, std::equal_to<>> tm;
63+
const std::unordered_multimap<StoredKey, int, TransparentKeyHash, std::equal_to<>> ctm;
64+
65+
TransparentKey tkey;
66+
67+
tm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
68+
ctm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
69+
#endif
70+
71+
#if TEST_STD_VER >= 20
72+
m.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
73+
cm.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
74+
75+
tm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
76+
ctm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
77+
#endif
78+
79+
m.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
80+
cm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
81+
#if TEST_STD_VER >= 20
82+
tm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
83+
ctm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
84+
#endif
85+
86+
m.bucket_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
87+
m.max_bucket_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
88+
89+
int size = 0;
90+
91+
m.bucket_size(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
92+
m.bucket(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
93+
94+
m.begin(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
95+
m.end(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
96+
cm.begin(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
97+
cm.end(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
98+
cm.cbegin(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
99+
cm.cend(size); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
100+
101+
m.load_factor(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
102+
m.max_load_factor(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
103+
}

0 commit comments

Comments
 (0)