Skip to content

Conversation

@H-G-Hristov
Copy link
Contributor

[[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
https://wg21.link/map

@H-G-Hristov H-G-Hristov requested a review from a team as a code owner November 29, 2025 05:24
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Nov 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 29, 2025

@llvm/pr-subscribers-libcxx

Author: Hristo Hristov (H-G-Hristov)

Changes

[[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
https://wg21.link/map


Patch is 21.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/169971.diff

4 Files Affected:

  • (modified) libcxx/include/__type_traits/is_generic_transparent_comparator.h (+1-1)
  • (modified) libcxx/include/map (+59-45)
  • (modified) libcxx/test/libcxx/diagnostics/map.nodiscard.verify.cpp (+114-8)
  • (added) libcxx/test/libcxx/diagnostics/multimap.nodiscard.verify copy.cpp (+18)
diff --git a/libcxx/include/__type_traits/is_generic_transparent_comparator.h b/libcxx/include/__type_traits/is_generic_transparent_comparator.h
index fd02c0b0423d1..7c1f0e984ed4b 100644
--- a/libcxx/include/__type_traits/is_generic_transparent_comparator.h
+++ b/libcxx/include/__type_traits/is_generic_transparent_comparator.h
@@ -17,7 +17,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// This traits returns true if the given _Comparator is known to accept any two types for compaison. This is separate
+// This trait returns true if the given _Comparator is known to accept any two types for comparison. This is separate
 // from `__is_transparent_v`, since that only enables overloads of specific functions, but doesn't give any semantic
 // guarantees. This trait guarantess that the comparator simply calls the appropriate comparison functions for any two
 // types.
diff --git a/libcxx/include/map b/libcxx/include/map
index 0dca11cabd12e..27fc7c0dea6ec 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -1027,33 +1027,37 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI ~map() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
 
-  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
-  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
-  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
-  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
 
-  _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
-  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
-  _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
-  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
+    return const_reverse_iterator(end());
+  }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
+    return const_reverse_iterator(begin());
+  }
 
-  _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
-  _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
-  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
-  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
 
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
-  _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
-  _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
 
-  _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
 #  ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
 #  endif
 
   template <class _Arg,
             __enable_if_t<__is_transparently_comparable_v<_Compare, key_type, __remove_cvref_t<_Arg> >, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI mapped_type& at(_Arg&& __arg) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& at(_Arg&& __arg) {
     auto [_, __child] = __tree_.__find_equal(__arg);
     if (__child == nullptr)
       std::__throw_out_of_range("map::at:  key not found");
@@ -1062,19 +1066,23 @@ public:
 
   template <class _Arg,
             __enable_if_t<__is_transparently_comparable_v<_Compare, key_type, __remove_cvref_t<_Arg> >, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI const mapped_type& at(_Arg&& __arg) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const mapped_type& at(_Arg&& __arg) const {
     auto [_, __child] = __tree_.__find_equal(__arg);
     if (__child == nullptr)
       std::__throw_out_of_range("map::at:  key not found");
     return static_cast<__node_pointer>(__child)->__get_value().second;
   }
 
-  _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
-  _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
 
-  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(__tree_.__alloc()); }
-  _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
-  _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__tree_.value_comp().key_comp()); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
+    return allocator_type(__tree_.__alloc());
+  }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const {
+    return value_compare(__tree_.value_comp().key_comp());
+  }
 
 #  ifndef _LIBCPP_CXX03_LANG
   template <class... _Args>
@@ -1226,10 +1234,10 @@ public:
                                         "node_type with incompatible allocator passed to map::insert()");
     return __tree_.template __node_handle_insert_unique<node_type>(__hint.__i_, std::move(__nh));
   }
-  _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
     return __tree_.template __node_handle_extract<node_type>(__key);
   }
-  _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
     return __tree_.template __node_handle_extract<node_type>(__it.__i_);
   }
   template <class _Compare2>
@@ -1260,44 +1268,48 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI void swap(map& __m) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__m.__tree_); }
 
-  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
-  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
 #  if _LIBCPP_STD_VER >= 14
   template <typename _K2,
             enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
                         int> = 0>
-  _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
     return __tree_.find(__k);
   }
   template <typename _K2,
             enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
                         int> = 0>
-  _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
     return __tree_.find(__k);
   }
 #  endif
 
-  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
+    return __tree_.__count_unique(__k);
+  }
 #  if _LIBCPP_STD_VER >= 14
   template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
     return __tree_.__count_multi(__k);
   }
 #  endif
 
 #  if _LIBCPP_STD_VER >= 20
-  _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
   template <typename _K2,
             enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
                         int> = 0>
-  _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
     return find(__k) != end();
   }
 #  endif // _LIBCPP_STD_VER >= 20
 
-  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.__lower_bound_unique(__k); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) {
+    return __tree_.__lower_bound_unique(__k);
+  }
 
-  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
     return __tree_.__lower_bound_unique(__k);
   }
 
@@ -1307,21 +1319,23 @@ public:
   template <typename _K2,
             enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
                         int> = 0>
-  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
     return __tree_.__lower_bound_multi(__k);
   }
 
   template <typename _K2,
             enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
                         int> = 0>
-  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
     return __tree_.__lower_bound_multi(__k);
   }
 #  endif
 
-  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.__upper_bound_unique(__k); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) {
+    return __tree_.__upper_bound_unique(__k);
+  }
 
-  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
     return __tree_.__upper_bound_unique(__k);
   }
 
@@ -1329,30 +1343,30 @@ public:
   template <typename _K2,
             enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
                         int> = 0>
-  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
     return __tree_.__upper_bound_multi(__k);
   }
   template <typename _K2,
             enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
                         int> = 0>
-  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
     return __tree_.__upper_bound_multi(__k);
   }
 #  endif
 
-  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
     return __tree_.__equal_range_unique(__k);
   }
-  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
     return __tree_.__equal_range_unique(__k);
   }
 #  if _LIBCPP_STD_VER >= 14
   template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
     return __tree_.__equal_range_multi(__k);
   }
   template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
     return __tree_.__equal_range_multi(__k);
   }
 #  endif
diff --git a/libcxx/test/libcxx/diagnostics/map.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/map.nodiscard.verify.cpp
index 78a8dd78f98a7..44f2fa3c5f590 100644
--- a/libcxx/test/libcxx/diagnostics/map.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/map.nodiscard.verify.cpp
@@ -8,16 +8,122 @@
 
 // UNSUPPORTED: c++03
 
-// check that <map> functions are marked [[nodiscard]]
+// Check that functions are marked [[nodiscard]]
 
 #include <map>
+#include <utility>
+#include <string>
 
-void map_test() {
-  std::map<int, int> map;
-  map.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}
+#include "test_macros.h"
+
+template <typename T>
+struct TransparentKey {
+  T t;
+
+  constexpr explicit operator T() const { return t; }
+};
+
+struct TransparentCompare {
+  using is_transparent = void; // This makes the comparator transparent
+
+  template <typename T>
+  constexpr bool operator()(const T& t, const TransparentKey<T>& transparent) const {
+    return t < transparent.t;
+  }
+
+  template <typename T>
+  constexpr bool operator()(const TransparentKey<T>& transparent, const T& t) const {
+    return transparent.t < t;
+  }
+
+  template <typename T>
+  constexpr bool operator()(const T& t1, const T& t2) const {
+    return t1 < t2;
+  }
+};
+
+void test() {
+  std::map<int, int, TransparentCompare> m;
+  const std::map<int, int, TransparentCompare> cm{};
+
+  m.begin();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.end();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.end();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  m.rbegin();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.rend();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.rend();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  cm.cbegin();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.cend();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.crend();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  m.empty();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.size();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  int key = 0;
+
+  m[key];            // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m[std::move(key)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  std::map<std::string, int, std::less<>> strMap;
+  const std::map<std::string, int, std::less<>> cstrMap{};
+
+  // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  strMap.at("zmt");
+  // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cstrMap.at("hkt");
+  m.at(key);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.at(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  m.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.key_comp();      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.value_comp();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 17
+  m.extract(key);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.extract(m.cend()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+  m.find(key);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 14
+  TransparentKey<int> tkey;
+
+  m.find(tkey);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+  m.count(key);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 20
+  m.contains(key);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+  m.lower_bound(key);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 14
+  m.lower_bound(tkey);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+  m.upper_bound(key);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 14
+  m.upper_bound(tkey);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
 
-void multimap_test() {
-  std::multimap<int, int> multimap;
-  multimap.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  m.equal_range(key);  // expected-warning {{ig...
[truncated]

@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/nodiscard-to-map branch 2 times, most recently from b8b4b98 to cf34b2f Compare November 29, 2025 05:59
[[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
https://wg21.link/map
@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/nodiscard-to-map branch from cf34b2f to c550382 Compare November 29, 2025 07:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants