Skip to content

Conversation

@H-G-Hristov
Copy link
Contributor

@H-G-Hristov H-G-Hristov commented Dec 4, 2025

[[nodiscard]] should be applied to functions where discarding the return value is most likely a correctness issue.

  1. hash<shared_ptr>, hash<unique_ptr>, std::integer_sequence<> etc.
  2. Also implements fixes to [libc++] std.functional.hash should be exported from Clang modules for some standard library headers #169634 on the go (issues discovered during current implementation)

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/nodiscard-to-hash branch 4 times, most recently from 9cec609 to fef23bd Compare December 4, 2025 17:06
@H-G-Hristov H-G-Hristov marked this pull request as ready for review December 4, 2025 17:42
@H-G-Hristov H-G-Hristov requested a review from a team as a code owner December 4, 2025 17:42
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Dec 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 4, 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.

  1. hash&lt;shared_ptr&gt;, hash&lt;unique_ptr&gt;, etc.
  2. Also implements fixes to [libc++] std.functional.hash should be exported from Clang modules for some standard library headers #169634 on the go (issues discovered during current implementation)

Full diff: https://github.com/llvm/llvm-project/pull/170674.diff

7 Files Affected:

  • (modified) libcxx/include/__functional/hash.h (+1-1)
  • (modified) libcxx/include/__memory/shared_ptr.h (+2-2)
  • (modified) libcxx/include/__memory/unique_ptr.h (+1-1)
  • (modified) libcxx/include/module.modulemap.in (+6-1)
  • (modified) libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp (+6)
  • (modified) libcxx/test/libcxx/language.support/nodiscard.verify.cpp (-1)
  • (modified) libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp (+11)
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/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/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@+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@+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;

@H-G-Hristov H-G-Hristov changed the title [libc++][hash] Applied [[nodiscard]] [libc++][hash] Applied [[nodiscard]] to hash<shared_ptr>, hash<unique_ptr>, etc. Dec 4, 2025
@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/nodiscard-to-hash branch from fef23bd to bf2987a Compare December 4, 2025 18:38
@H-G-Hristov H-G-Hristov changed the title [libc++][hash] Applied [[nodiscard]] to hash<shared_ptr>, hash<unique_ptr>, etc. [libc++] Applied [[nodiscard]] to hash<shared_ptr>, hash<unique_ptr>, etc. Dec 4, 2025
`[[nodiscard]]`` should be applied to functions where discarding the return value is most likely a correctness issue.

- https://libcxx.llvm.org/CodingGuidelines.html
@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/nodiscard-to-hash branch from bf2987a to 3ad03ea Compare December 4, 2025 18:51
@H-G-Hristov
Copy link
Contributor Author

@frederick-vs-ja Sorry again! Can we merge this too?

@H-G-Hristov
Copy link
Contributor Author

Thank you!

@Zingam Zingam merged commit 4125e73 into llvm:main Dec 8, 2025
80 checks passed
honeygoyal pushed a commit to honeygoyal/llvm-project that referenced this pull request Dec 9, 2025
…ptr>`, etc. (llvm#170674)

`[[nodiscard]]` should be applied to functions where discarding the
return value is most likely a correctness issue.

- https://libcxx.llvm.org/CodingGuidelines.html


1. `hash<shared_ptr>`, `hash<unique_ptr>`, `std::integer_sequence<>`
etc.
2. Also implements fixes to
llvm#169634 on the go (issues
discovered during current implementation)

---------

Co-authored-by: A. Jiang <[email protected]>
Co-authored-by: Hristo Hristov <[email protected]>
@H-G-Hristov H-G-Hristov deleted the hgh/libcxx/nodiscard-to-hash branch December 11, 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.

4 participants