[libcxx-commits] [libcxx] [libc++] Applied `[[nodiscard]]` to `hash<shared_ptr>`, `hash<unique_ptr>`, etc. (PR #170674)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Dec 6 06:14:07 PST 2025
https://github.com/Zingam updated https://github.com/llvm/llvm-project/pull/170674
>From 3ad03ea103e4e2cbef59499408e92fba4a6e4beb Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 4 Dec 2025 17:08:08 +0200
Subject: [PATCH 1/2] [libc++][hash] Applied `[[nodiscard]]`
`[[nodiscard]]`` should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html
---
libcxx/include/__functional/hash.h | 2 +-
libcxx/include/__memory/shared_ptr.h | 4 ++--
libcxx/include/__memory/unique_ptr.h | 2 +-
libcxx/include/__utility/integer_sequence.h | 2 +-
libcxx/include/module.modulemap.in | 7 ++++++-
.../functional.nodiscard.verify.cpp | 6 ++++++
.../language.support/nodiscard.verify.cpp | 1 -
.../utilities/intseq/nodiscard.verify.cpp | 21 +++++++++++++++++++
.../utilities/smartptr/nodiscard.verify.cpp | 11 ++++++++++
9 files changed, 49 insertions(+), 7 deletions(-)
create mode 100644 libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp
diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h
index f74f25fa6e84b..d81ff1abbdaba 100644
--- a/libcxx/include/__functional/hash.h
+++ b/libcxx/include/__functional/hash.h
@@ -435,7 +435,7 @@ struct hash : public __hash_impl<_Tp> {};
template <>
struct hash<nullptr_t> : public __unary_function<nullptr_t, size_t> {
- _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; }
};
#ifndef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 6eddc4daa4184..4fbd0af98463e 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -77,7 +77,7 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception {
_LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI bad_weak_ptr& operator=(const bad_weak_ptr&) _NOEXCEPT = default;
~bad_weak_ptr() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
};
[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() {
@@ -1423,7 +1423,7 @@ struct hash<shared_ptr<_Tp> > {
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
#endif
- _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT {
return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
}
};
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index b5f469365daed..6a4ec0a466ba7 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -800,7 +800,7 @@ struct hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp,
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
#endif
- _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {
typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
return hash<pointer>()(__ptr.get());
}
diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h
index 329826ae5eda2..e3a597584cc0f 100644
--- a/libcxx/include/__utility/integer_sequence.h
+++ b/libcxx/include/__utility/integer_sequence.h
@@ -33,7 +33,7 @@ template <class _Tp, _Tp... _Indices>
struct __integer_sequence {
using value_type = _Tp;
static_assert(is_integral<_Tp>::value, "std::integer_sequence can only be instantiated with an integral type");
- static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); }
+ [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); }
};
template <size_t... _Indices>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 0ac5a1ade817f..c473b4a2c2d23 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1660,7 +1660,10 @@ module std [system] {
}
module raw_storage_iterator { header "__memory/raw_storage_iterator.h" }
module shared_count { header "__memory/shared_count.h" }
- module shared_ptr { header "__memory/shared_ptr.h" }
+ module shared_ptr {
+ header "__memory/shared_ptr.h"
+ export std.functional.hash
+ }
module swap_allocator { header "__memory/swap_allocator.h" }
module temp_value { header "__memory/temp_value.h" }
module temporary_buffer {
@@ -1673,6 +1676,7 @@ module std [system] {
}
module unique_ptr {
header "__memory/unique_ptr.h"
+ export std.functional.hash
}
module unique_temporary_buffer {
header "__memory/unique_temporary_buffer.h"
@@ -2391,6 +2395,7 @@ module std [system] {
header "coroutine"
export *
+ export std.functional.hash
}
} // module std
diff --git a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
index 898b2ac06e3f2..521870f2484a2 100644
--- a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
@@ -10,6 +10,7 @@
// check that <functional> functions are marked [[nodiscard]]
+#include <cstddef>
#include <functional>
#include "test_macros.h"
@@ -59,4 +60,9 @@ void test() {
std::ref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::cref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Hash specializations
+
+ std::hash<std::nullptr_t> hash;
+ hash(nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
index b87b04ad9f1ef..b8f3a8a6e5ce2 100644
--- a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
@@ -12,7 +12,6 @@
#include <compare>
#include <coroutine>
-#include <functional>
#include <initializer_list>
#include "test_macros.h"
diff --git a/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..4a5d90616935f
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <utility>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <utility>
+
+void test() {
+ std::integer_sequence<int, 49, 82, 94> seq;
+
+ seq.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
index 66e00d6fa66c0..6e713fe5217ba 100644
--- a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
@@ -41,6 +41,14 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::make_unique_for_overwrite<int[]>(5);
#endif
+
+ std::hash<std::unique_ptr<int>> hash;
+ hash(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ { // [util.smartptr.weak.bad]
+ std::bad_weak_ptr bwp;
+
+ bwp.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{ // [util.sharedptr]
std::shared_ptr<int[]> sPtr;
@@ -118,6 +126,9 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::get_deleter<int[]>(sPtr);
#endif
+
+ std::hash<std::shared_ptr<int[]>> hash;
+ hash(sPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{ // [util.smartptr.weak]
std::weak_ptr<int> wPtr;
>From e23a84f1a9606a73378a920cc916e3dd23569408 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hristo.goshev.hristov at gmail.com>
Date: Fri, 5 Dec 2025 08:02:51 +0200
Subject: [PATCH 2/2] Apply suggestion from @frederick-vs-ja
Co-authored-by: A. Jiang <de34 at live.cn>
---
libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp
index 4a5d90616935f..4ca52ace08dd3 100644
--- a/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03
+// REQUIRES: std-at-least-c++14
// <utility>
More information about the libcxx-commits
mailing list