[libcxx-commits] [libcxx] [libc++] Add [[gnu::warn_unused]] to a bunch of threading utilities (PR #213963)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Tue Aug 11 02:16:28 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/213963

>From d695c2ead10ba6de00deb33e7c336ff03b0d88a9 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 4 Aug 2026 16:34:23 +0200
Subject: [PATCH] [libc++] Add [[gnu::warn_unused]] to a bunch of threading
 utilities

---
 .../__condition_variable/condition_variable.h |  2 +-
 libcxx/include/__mutex/mutex.h                |  2 +-
 libcxx/include/__mutex/once_flag.h            |  2 +-
 libcxx/include/barrier                        |  2 +-
 libcxx/include/condition_variable             |  2 +-
 libcxx/include/mutex                          |  6 +--
 libcxx/include/shared_mutex                   |  4 +-
 .../diagnostics/unused_variables.verify.cpp   | 51 +++++++++++++++++++
 .../test/libcxx/thread/nodiscard.verify.cpp   |  2 +-
 .../default.pass.cpp                          |  6 +--
 10 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/libcxx/include/__condition_variable/condition_variable.h b/libcxx/include/__condition_variable/condition_variable.h
index e15113ced5758..a29b66152981d 100644
--- a/libcxx/include/__condition_variable/condition_variable.h
+++ b/libcxx/include/__condition_variable/condition_variable.h
@@ -87,7 +87,7 @@ inline _LIBCPP_HIDE_FROM_ABI chrono::nanoseconds __safe_nanosecond_cast(chrono::
   return nanoseconds(__result);
 }
 
-class _LIBCPP_EXPORTED_FROM_ABI condition_variable {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_WARN_UNUSED condition_variable {
   __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
 
 public:
diff --git a/libcxx/include/__mutex/mutex.h b/libcxx/include/__mutex/mutex.h
index f71cba03cd4dc..699783ec7929d 100644
--- a/libcxx/include/__mutex/mutex.h
+++ b/libcxx/include/__mutex/mutex.h
@@ -22,7 +22,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
-class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("mutex") mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("mutex") _LIBCPP_WARN_UNUSED mutex {
   __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
 
 public:
diff --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h
index 9999852b8b78a..212cfaf2cd669 100644
--- a/libcxx/include/__mutex/once_flag.h
+++ b/libcxx/include/__mutex/once_flag.h
@@ -47,7 +47,7 @@ _LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, const _Callable&);
 
 #endif // _LIBCPP_CXX03_LANG
 
-struct once_flag {
+struct _LIBCPP_WARN_UNUSED once_flag {
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(_Unset) {}
   once_flag(const once_flag&)            = delete;
   once_flag& operator=(const once_flag&) = delete;
diff --git a/libcxx/include/barrier b/libcxx/include/barrier
index f4f48f02ae2cb..b7ffa1d930b95 100644
--- a/libcxx/include/barrier
+++ b/libcxx/include/barrier
@@ -151,7 +151,7 @@ public:
 };
 
 template <class _CompletionF = __empty_completion>
-class barrier {
+class _LIBCPP_WARN_UNUSED barrier {
   __barrier_base<_CompletionF> __b_;
 
 public:
diff --git a/libcxx/include/condition_variable b/libcxx/include/condition_variable
index cefb3ffff879f..f294ded2ff05b 100644
--- a/libcxx/include/condition_variable
+++ b/libcxx/include/condition_variable
@@ -163,7 +163,7 @@ struct __unlock_guard {
   __unlock_guard& operator=(const __unlock_guard&) = delete;
 };
 
-class _LIBCPP_EXPORTED_FROM_ABI condition_variable_any {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_WARN_UNUSED condition_variable_any {
   condition_variable __cv_;
   shared_ptr<mutex> __mut_;
 
diff --git a/libcxx/include/mutex b/libcxx/include/mutex
index 24e6cab850c46..412dff50a17ad 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -219,7 +219,7 @@ _LIBCPP_PUSH_MACROS
 _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
-class _LIBCPP_EXPORTED_FROM_ABI recursive_mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_WARN_UNUSED recursive_mutex {
   __libcpp_recursive_mutex_t __m_;
 
 public:
@@ -238,7 +238,7 @@ public:
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
 };
 
-class _LIBCPP_EXPORTED_FROM_ABI timed_mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_WARN_UNUSED timed_mutex {
   mutex __m_;
   condition_variable __cv_;
   bool __locked_;
@@ -275,7 +275,7 @@ public:
   void unlock() _NOEXCEPT;
 };
 
-class _LIBCPP_EXPORTED_FROM_ABI recursive_timed_mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_WARN_UNUSED recursive_timed_mutex {
   mutex __m_;
   condition_variable __cv_;
   size_t __count_;
diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index 2dfcb4f26f9d2..9b635d65fd7b5 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -185,7 +185,7 @@ struct _LIBCPP_EXPORTED_FROM_ABI __shared_mutex_base {
 };
 
 #      if _LIBCPP_STD_VER >= 17
-class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("shared_mutex") shared_mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("shared_mutex") _LIBCPP_WARN_UNUSED shared_mutex {
   __shared_mutex_base __base_;
 
 public:
@@ -214,7 +214,7 @@ public:
 };
 #      endif
 
-class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("shared_timed_mutex") shared_timed_mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("shared_timed_mutex") _LIBCPP_WARN_UNUSED shared_timed_mutex {
   __shared_mutex_base __base_;
 
 public:
diff --git a/libcxx/test/libcxx/diagnostics/unused_variables.verify.cpp b/libcxx/test/libcxx/diagnostics/unused_variables.verify.cpp
index c36e32d67e37f..c3501503bb7d8 100644
--- a/libcxx/test/libcxx/diagnostics/unused_variables.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/unused_variables.verify.cpp
@@ -8,16 +8,24 @@
 
 // Make sure that we warn on unused variables of libc++ classes which behave like value types.
 
+#include <barrier>
+#include <condition_variable>
 #include <deque>
 #include <forward_list>
+#include <latch>
 #include <list>
 #include <map>
+#include <mutex>
+#include <semaphore>
 #include <set>
+#include <shared_mutex>
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
 #include <vector>
 
+#include "test_macros.h"
+
 void containers() {
   std::deque<int> a;                   // expected-warning {{unused variable}}
   std::forward_list<int> b;            // expected-warning {{unused variable}}
@@ -68,3 +76,46 @@ void container_const_iterators() {
   std::vector<int>::const_iterator m;                  // expected-warning {{unused variable}}
   std::vector<bool>::const_iterator n;                 // expected-warning {{unused variable}}
 }
+
+void synchronization(std::mutex& m) {
+  // <mutex>
+  std::mutex a;                      // expected-warning {{unused variable}}
+  std::once_flag b;                  // expected-warning {{unused variable}}
+  std::recursive_mutex c;            // expected-warning {{unused variable}}
+  std::recursive_timed_mutex d;      // expected-warning {{unused variable}}
+  std::timed_mutex e;                // expected-warning {{unused variable}}
+  std::unique_lock<std::mutex> f;    // TODO: We should warn on this
+  std::unique_lock<std::mutex> g(m); // Shouldn't be diagnosed
+#if TEST_STD_VER >= 17
+  std::unique_lock<std::mutex> h(m, std::defer_lock); // TODO: We should warn on this
+#endif
+
+  // <condition_variable>
+  std::condition_variable i;     // expected-warning {{unused variable}}
+  std::condition_variable_any j; // expected-warning {{unused variable}}
+
+#if TEST_STD_VER >= 20
+  // <semaphore>
+  std::counting_semaphore<> k(1); // expected-warning {{unused variable}}
+#endif
+
+  // <shared_mutex>
+#if TEST_STD_VER >= 17
+  std::shared_mutex l; // expected-warning {{unused variable}}
+#endif
+#if TEST_STD_VER >= 14
+  std::shared_timed_mutex n; // expected-warning {{unused variable}}
+  std::shared_timed_mutex n2;
+  std::shared_lock<std::shared_timed_mutex> o;                      // TODO: We should warn on this
+  std::shared_lock<std::shared_timed_mutex> p(n2);                  // Shouldn't be diagnosed
+  std::shared_lock<std::shared_timed_mutex> q(n2, std::defer_lock); // TODO: We should warn on this
+#endif
+
+#if TEST_STD_VER >= 20
+  // <barrier>
+  std::barrier<> r(1); // expected-warning {{unused variable}}
+
+  // <latch>
+  std::latch s(1); // expected-warning {{unused variable}}
+#endif
+}
diff --git a/libcxx/test/libcxx/thread/nodiscard.verify.cpp b/libcxx/test/libcxx/thread/nodiscard.verify.cpp
index 8af921494e26b..a8a3ebe641764 100644
--- a/libcxx/test/libcxx/thread/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/thread/nodiscard.verify.cpp
@@ -312,11 +312,11 @@ void test() {
   {
     std::mutex m1;
     std::mutex m2;
-    std::mutex m3;
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     std::try_lock(m1, m2);
 #if TEST_STD_VER >= 11
+    std::mutex m3;
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     std::try_lock(m1, m2, m3);
 #endif
diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp
index 0cf70ad3c517b..7c576d77134d6 100644
--- a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp
+++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp
@@ -19,9 +19,9 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    std::condition_variable_any cv;
+int main(int, char**) {
+  std::condition_variable_any cv;
+  (void)cv;
 
   return 0;
 }



More information about the libcxx-commits mailing list