[libcxx-commits] [libcxx] 22f8ced - [libc++] Add the thread safety annotations unconditionally (#117497)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jul 5 09:07:11 PDT 2025


Author: Nikolas Klauser
Date: 2025-07-05T18:07:07+02:00
New Revision: 22f8ceded4e1c20e6113049bfceec4a8b56b92a5

URL: https://github.com/llvm/llvm-project/commit/22f8ceded4e1c20e6113049bfceec4a8b56b92a5
DIFF: https://github.com/llvm/llvm-project/commit/22f8ceded4e1c20e6113049bfceec4a8b56b92a5.diff

LOG: [libc++] Add the thread safety annotations unconditionally (#117497)

For these annotations to do anything you need `-Wthread-safety`, in
which case users most likely enable them anyways. This avoids that users
have to explictly define a macro just to use the feature they already
had to opt-in to.

Added: 
    

Modified: 
    libcxx/.clang-format
    libcxx/docs/UserDocumentation.rst
    libcxx/include/__config
    libcxx/include/__mutex/lock_guard.h
    libcxx/include/__mutex/mutex.h
    libcxx/include/mutex
    libcxx/include/shared_mutex
    libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp
    libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
    libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp
    libcxx/test/libcxx/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp
    libcxx/test/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp
    libcxx/test/libcxx/thread/thread.shared_mutex/thread_safety.verify.cpp
    libcxx/test/libcxx/thread/thread.shared_timed_mutex/thread_safety.verify.cpp
    libcxx/utils/libcxx/test/features.py

Removed: 
    


################################################################################
diff  --git a/libcxx/.clang-format b/libcxx/.clang-format
index fe2f2ef0119fa..f372ac9619997 100644
--- a/libcxx/.clang-format
+++ b/libcxx/.clang-format
@@ -16,8 +16,11 @@ AllowShortLambdasOnASingleLine: All
 AttributeMacros: [
                   '_ALIGNAS_TYPE',
                   '_ALIGNAS',
+                  '_LIBCPP_ACQUIRE_CAPABILITY',
+                  '_LIBCPP_ACQUIRE_SHARED_CAPABILITY',
                   '_LIBCPP_ALIGNOF',
                   '_LIBCPP_ALWAYS_INLINE',
+                  '_LIBCPP_CAPABILITY',
                   '_LIBCPP_CONSTEXPR_SINCE_CXX14',
                   '_LIBCPP_CONSTEXPR_SINCE_CXX17',
                   '_LIBCPP_CONSTEXPR_SINCE_CXX20',
@@ -41,9 +44,13 @@ AttributeMacros: [
                   '_LIBCPP_NO_UNIQUE_ADDRESS',
                   '_LIBCPP_NOALIAS',
                   '_LIBCPP_OVERRIDABLE_FUNC_VIS',
+                  '_LIBCPP_RELEASE_CAPABILITY',
+                  '_LIBCPP_REQUIRES_CAPABILITY',
+                  '_LIBCPP_SCOPED_LOCKABLE',
                   '_LIBCPP_STANDALONE_DEBUG',
                   '_LIBCPP_TEMPLATE_DATA_VIS',
-                  '_LIBCPP_THREAD_SAFETY_ANNOTATION',
+                  '_LIBCPP_TRY_ACQUIRE_CAPABILITY',
+                  '_LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY',
                   '_LIBCPP_USING_IF_EXISTS',
                   '_LIBCPP_WEAK',
                  ]

diff  --git a/libcxx/docs/UserDocumentation.rst b/libcxx/docs/UserDocumentation.rst
index f82554a4869fa..79f5908bdc6b6 100644
--- a/libcxx/docs/UserDocumentation.rst
+++ b/libcxx/docs/UserDocumentation.rst
@@ -114,11 +114,6 @@ enable or disable extended libc++ behavior.
   ensure that the appropriate experimental library (usually ``libc++experimental.a``)
   is linked into their program.
 
-**_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS**:
-  This macro is used to enable -Wthread-safety annotations on libc++'s
-  ``std::mutex`` and ``std::lock_guard``. By default, these annotations are
-  disabled and must be manually enabled by the user.
-
 **_LIBCPP_HARDENING_MODE**:
   This macro is used to choose the :ref:`hardening mode <using-hardening-modes>`.
 

diff  --git a/libcxx/include/__config b/libcxx/include/__config
index af8a297fdf3fd..58ca9bab937e4 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -903,23 +903,6 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
 #  endif
 
-// Work around the attribute handling in clang.  When both __declspec and
-// __attribute__ are present, the processing goes awry preventing the definition
-// of the types. In MinGW mode, __declspec evaluates to __attribute__, and thus
-// combining the two does work.
-#  if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && defined(__clang__) &&                                       \
-      __has_attribute(acquire_capability) && !defined(_MSC_VER)
-#    define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS 1
-#  else
-#    define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS 0
-#  endif
-
-#  if _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
-#    define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
-#  else
-#    define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
-#  endif
-
 #  if _LIBCPP_STD_VER >= 20
 #    define _LIBCPP_CONSTINIT constinit
 #  elif __has_attribute(__require_constant_initialization__)
@@ -1147,6 +1130,60 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_PREFERRED_NAME(x)
 #  endif
 
+#  if __has_cpp_attribute(_Clang::__scoped_lockable__)
+#    define _LIBCPP_SCOPED_LOCKABLE [[_Clang::__scoped_lockable__]]
+#  else
+#    define _LIBCPP_SCOPED_LOCKABLE
+#  endif
+
+#  if __has_cpp_attribute(_Clang::__capability__)
+#    define _LIBCPP_CAPABILITY(...) [[_Clang::__capability__(__VA_ARGS__)]]
+#  else
+#    define _LIBCPP_CAPABILITY(...)
+#  endif
+
+#  if __has_attribute(__acquire_capability__)
+#    define _LIBCPP_ACQUIRE_CAPABILITY(...) __attribute__((__acquire_capability__(__VA_ARGS__)))
+#  else
+#    define _LIBCPP_ACQUIRE_CAPABILITY(...)
+#  endif
+
+#  if __has_cpp_attribute(_Clang::__try_acquire_capability__)
+#    define _LIBCPP_TRY_ACQUIRE_CAPABILITY(...) [[_Clang::__try_acquire_capability__(__VA_ARGS__)]]
+#  else
+#    define _LIBCPP_TRY_ACQUIRE_CAPABILITY(...)
+#  endif
+
+#  if __has_cpp_attribute(_Clang::__acquire_shared_capability__)
+#    define _LIBCPP_ACQUIRE_SHARED_CAPABILITY [[_Clang::__acquire_shared_capability__]]
+#  else
+#    define _LIBCPP_ACQUIRE_SHARED_CAPABILITY
+#  endif
+
+#  if __has_cpp_attribute(_Clang::__try_acquire_shared_capability__)
+#    define _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(...) [[_Clang::__try_acquire_shared_capability__(__VA_ARGS__)]]
+#  else
+#    define _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(...)
+#  endif
+
+#  if __has_cpp_attribute(_Clang::__release_capability__)
+#    define _LIBCPP_RELEASE_CAPABILITY [[_Clang::__release_capability__]]
+#  else
+#    define _LIBCPP_RELEASE_CAPABILITY
+#  endif
+
+#  if __has_cpp_attribute(_Clang::__release_shared_capability__)
+#    define _LIBCPP_RELEASE_SHARED_CAPABILITY [[_Clang::__release_shared_capability__]]
+#  else
+#    define _LIBCPP_RELEASE_SHARED_CAPABILITY
+#  endif
+
+#  if __has_attribute(__requires_capability__)
+#    define _LIBCPP_REQUIRES_CAPABILITY(...) __attribute__((__requires_capability__(__VA_ARGS__)))
+#  else
+#    define _LIBCPP_REQUIRES_CAPABILITY(...)
+#  endif
+
 #  if defined(_LIBCPP_ABI_MICROSOFT) && __has_declspec_attribute(empty_bases)
 #    define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
 #  else

diff  --git a/libcxx/include/__mutex/lock_guard.h b/libcxx/include/__mutex/lock_guard.h
index a529c552a1df0..67a25ed2f8a89 100644
--- a/libcxx/include/__mutex/lock_guard.h
+++ b/libcxx/include/__mutex/lock_guard.h
@@ -19,7 +19,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Mutex>
-class _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard {
+class _LIBCPP_SCOPED_LOCKABLE lock_guard {
 public:
   typedef _Mutex mutex_type;
 
@@ -27,16 +27,14 @@ class _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard {
   mutex_type& __m_;
 
 public:
-  [[__nodiscard__]]
-  _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) _LIBCPP_ACQUIRE_CAPABILITY(__m)
       : __m_(__m) {
     __m_.lock();
   }
 
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t)
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_REQUIRES_CAPABILITY(__m)
       : __m_(__m) {}
-  _LIBCPP_HIDE_FROM_ABI ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); }
+  _LIBCPP_RELEASE_CAPABILITY _LIBCPP_HIDE_FROM_ABI ~lock_guard() { __m_.unlock(); }
 
   lock_guard(lock_guard const&)            = delete;
   lock_guard& operator=(lock_guard const&) = delete;

diff  --git a/libcxx/include/__mutex/mutex.h b/libcxx/include/__mutex/mutex.h
index 317320287902f..68c8842b35eda 100644
--- a/libcxx/include/__mutex/mutex.h
+++ b/libcxx/include/__mutex/mutex.h
@@ -21,7 +21,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("mutex") mutex {
   __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
 
 public:
@@ -36,9 +36,9 @@ class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mut
   ~mutex() _NOEXCEPT;
 #  endif
 
-  void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
-  bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
-  void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
+  _LIBCPP_ACQUIRE_CAPABILITY() void lock();
+  _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT;
+  _LIBCPP_RELEASE_CAPABILITY void unlock() _NOEXCEPT;
 
   typedef __libcpp_mutex_t* native_handle_type;
   _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }

diff  --git a/libcxx/include/mutex b/libcxx/include/mutex
index f616bad3ac171..dc8e711f04878 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -434,7 +434,7 @@ public:
 };
 
 template <class _Mutex>
-class _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) scoped_lock<_Mutex> {
+class _LIBCPP_SCOPED_LOCKABLE scoped_lock<_Mutex> {
 public:
   typedef _Mutex mutex_type;
 
@@ -442,16 +442,15 @@ private:
   mutex_type& __m_;
 
 public:
-  [[nodiscard]]
-  _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(mutex_type& __m) _LIBCPP_ACQUIRE_CAPABILITY(__m)
       : __m_(__m) {
     __m_.lock();
   }
 
-  ~scoped_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); }
+  _LIBCPP_RELEASE_CAPABILITY _LIBCPP_HIDE_FROM_ABI ~scoped_lock() { __m_.unlock(); }
 
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(adopt_lock_t, mutex_type& __m)
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
+  [[nodiscard]]
+  _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(adopt_lock_t, mutex_type& __m) _LIBCPP_REQUIRES_CAPABILITY(__m)
       : __m_(__m) {}
 
   scoped_lock(scoped_lock const&)            = delete;

diff  --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index 6469c02ca5874..8c02e348e4de7 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -183,7 +183,7 @@ struct _LIBCPP_EXPORTED_FROM_ABI __shared_mutex_base {
 };
 
 #      if _LIBCPP_STD_VER >= 17
-class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_mutex")) shared_mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("shared_mutex") shared_mutex {
   __shared_mutex_base __base_;
 
 public:
@@ -194,35 +194,23 @@ public:
   shared_mutex& operator=(const shared_mutex&) = delete;
 
   // Exclusive ownership
-  _LIBCPP_HIDE_FROM_ABI void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__()) {
-    return __base_.lock();
-  }
-  _LIBCPP_HIDE_FROM_ABI bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
-    return __base_.try_lock();
-  }
-  _LIBCPP_HIDE_FROM_ABI void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__()) {
-    return __base_.unlock();
-  }
+  _LIBCPP_ACQUIRE_CAPABILITY() _LIBCPP_HIDE_FROM_ABI void lock() { return __base_.lock(); }
+  _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) _LIBCPP_HIDE_FROM_ABI bool try_lock() { return __base_.try_lock(); }
+  _LIBCPP_RELEASE_CAPABILITY _LIBCPP_HIDE_FROM_ABI void unlock() { return __base_.unlock(); }
 
   // Shared ownership
-  _LIBCPP_HIDE_FROM_ABI void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__()) {
-    return __base_.lock_shared();
-  }
-  _LIBCPP_HIDE_FROM_ABI bool try_lock_shared()
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
+  _LIBCPP_ACQUIRE_SHARED_CAPABILITY _LIBCPP_HIDE_FROM_ABI void lock_shared() { return __base_.lock_shared(); }
+  _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(true) _LIBCPP_HIDE_FROM_ABI bool try_lock_shared() {
     return __base_.try_lock_shared();
   }
-  _LIBCPP_HIDE_FROM_ABI void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__()) {
-    return __base_.unlock_shared();
-  }
+  _LIBCPP_RELEASE_SHARED_CAPABILITY _LIBCPP_HIDE_FROM_ABI void unlock_shared() { return __base_.unlock_shared(); }
 
   //     typedef __shared_mutex_base::native_handle_type native_handle_type;
   //     _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return __base::unlock_shared(); }
 };
 #      endif
 
-class _LIBCPP_EXPORTED_FROM_ABI
-_LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_timed_mutex")) shared_timed_mutex {
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("shared_timed_mutex") shared_timed_mutex {
   __shared_mutex_base __base_;
 
 public:
@@ -233,17 +221,17 @@ public:
   shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
 
   // Exclusive ownership
-  void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__());
-  bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true));
+  void lock() _LIBCPP_ACQUIRE_CAPABILITY();
+  _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock();
   template <class _Rep, class _Period>
-  _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
+  _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) _LIBCPP_HIDE_FROM_ABI bool
+  try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) {
     return try_lock_until(chrono::steady_clock::now() + __rel_time);
   }
 
   template <class _Clock, class _Duration>
-  _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
+  _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) _LIBCPP_HIDE_FROM_ABI bool
+  try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) {
     unique_lock<mutex> __lk(__base_.__mut_);
     if (__base_.__state_ & __base_.__write_entered_) {
       while (true) {
@@ -270,20 +258,20 @@ public:
     return true;
   }
 
-  void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__());
+  _LIBCPP_RELEASE_CAPABILITY void unlock();
 
   // Shared ownership
-  void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__());
-  bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true));
+  _LIBCPP_ACQUIRE_SHARED_CAPABILITY void lock_shared();
+  _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(true) bool try_lock_shared();
   template <class _Rep, class _Period>
-  _LIBCPP_HIDE_FROM_ABI bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
+  _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(true) _LIBCPP_HIDE_FROM_ABI bool
+  try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) {
     return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
   }
 
   template <class _Clock, class _Duration>
-  _LIBCPP_HIDE_FROM_ABI bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
+  _LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY(true) _LIBCPP_HIDE_FROM_ABI bool
+  try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) {
     unique_lock<mutex> __lk(__base_.__mut_);
     if ((__base_.__state_ & __base_.__write_entered_) ||
         (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_) {
@@ -302,7 +290,7 @@ public:
     return true;
   }
 
-  void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__());
+  _LIBCPP_RELEASE_SHARED_CAPABILITY void unlock_shared();
 };
 
 template <class _Mutex>

diff  --git a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp
index 5d40fa71a4152..f43ad5b8c188a 100644
--- a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp
+++ b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp
@@ -11,9 +11,8 @@
 
 // <mutex>
 
-// This test does not define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS so it
-// should compile without any warnings or errors even though this pattern is not
-// understood by the thread safety annotations.
+// This test does not set -Wthread-safety so it should compile without any warnings or errors even though this pattern
+// is not understood by the thread safety annotations.
 
 #include <mutex>
 

diff  --git a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
index 1c1f36459c837..9633982774e1f 100644
--- a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
+++ b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
@@ -6,16 +6,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// On Windows Clang bugs out when both __declspec and __attribute__ are present,
-// the processing goes awry preventing the definition of the types.
-// XFAIL: msvc
-
 // UNSUPPORTED: no-threads
-// REQUIRES: thread-safety
 
 // <mutex>
 
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+// GCC doesn't have thread safety attributes
+// UNSUPPORTED: gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -Wthread-safety
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
 
 #include <mutex>
 

diff  --git a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp
index ddfe3269fdfa7..965d1444a4d5d 100644
--- a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp
+++ b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp
@@ -6,16 +6,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// On Windows Clang bugs out when both __declspec and __attribute__ are present,
-// the processing goes awry preventing the definition of the types.
-// XFAIL: msvc
-
 // UNSUPPORTED: no-threads
-// REQUIRES: thread-safety
 
 // <mutex>
 
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+// GCC doesn't have thread safety attributes
+// UNSUPPORTED: gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -Wthread-safety
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
 
 #include <mutex>
 

diff  --git a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp
index bab686e7b4ca2..4ae22219b0308 100644
--- a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp
+++ b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp
@@ -6,21 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 
-// On Windows Clang bugs out when both __declspec and __attribute__ are present,
-// the processing goes awry preventing the definition of the types.
-// XFAIL: msvc
-
 // UNSUPPORTED: no-threads
-// REQUIRES: thread-safety
 
 // <mutex>
 
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+// GCC doesn't have thread safety attributes
+// UNSUPPORTED: gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -Wthread-safety
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
 
 #include <mutex>
 
 std::mutex m;
 
-void f() {
-  m.lock();
-} // expected-error {{mutex 'm' is still held at the end of function}}
+void f() { m.lock(); } // expected-warning {{mutex 'm' is still held at the end of function}}

diff  --git a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp
index 81ce3b25a8394..e9794acc89414 100644
--- a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp
+++ b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp
@@ -6,16 +6,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// On Windows Clang bugs out when both __declspec and __attribute__ are present,
-// the processing goes awry preventing the definition of the types.
-// XFAIL: msvc
-
 // UNSUPPORTED: no-threads
-// REQUIRES: thread-safety
 
 // <mutex>
 
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+// GCC doesn't have thread safety attributes
+// UNSUPPORTED: gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -Wthread-safety
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
 
 #include <mutex>
 

diff  --git a/libcxx/test/libcxx/thread/thread.shared_mutex/thread_safety.verify.cpp b/libcxx/test/libcxx/thread/thread.shared_mutex/thread_safety.verify.cpp
index fee940fff847b..d87a70927819b 100644
--- a/libcxx/test/libcxx/thread/thread.shared_mutex/thread_safety.verify.cpp
+++ b/libcxx/test/libcxx/thread/thread.shared_mutex/thread_safety.verify.cpp
@@ -8,12 +8,11 @@
 
 // UNSUPPORTED: c++03, c++11, c++14
 // UNSUPPORTED: no-threads
-// REQUIRES: thread-safety
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
 
-// On Windows Clang bugs out when both __declspec and __attribute__ are present,
-// the processing goes awry preventing the definition of the types.
-// XFAIL: msvc
+// GCC doesn't have thread safety attributes
+// UNSUPPORTED: gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -Wthread-safety
 
 // <shared_mutex>
 //
@@ -51,13 +50,13 @@ void f() {
   {
     m.lock_shared();
     read(data); // ok
-    ++data; // expected-error {{writing variable 'data' requires holding shared_mutex 'm' exclusively}}
+    ++data;     // expected-warning {{writing variable 'data' requires holding shared_mutex 'm' exclusively}}
     m.unlock_shared();
   }
   {
     if (m.try_lock_shared()) {
       read(data); // ok
-      ++data; // expected-error {{writing variable 'data' requires holding shared_mutex 'm' exclusively}}
+      ++data;     // expected-warning {{writing variable 'data' requires holding shared_mutex 'm' exclusively}}
       m.unlock_shared();
     }
   }

diff  --git a/libcxx/test/libcxx/thread/thread.shared_timed_mutex/thread_safety.verify.cpp b/libcxx/test/libcxx/thread/thread.shared_timed_mutex/thread_safety.verify.cpp
index baa8bc614f149..9c16caa3631fb 100644
--- a/libcxx/test/libcxx/thread/thread.shared_timed_mutex/thread_safety.verify.cpp
+++ b/libcxx/test/libcxx/thread/thread.shared_timed_mutex/thread_safety.verify.cpp
@@ -8,12 +8,11 @@
 
 // UNSUPPORTED: c++03, c++11
 // UNSUPPORTED: no-threads
-// REQUIRES: thread-safety
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
 
-// On Windows Clang bugs out when both __declspec and __attribute__ are present,
-// the processing goes awry preventing the definition of the types.
-// XFAIL: msvc
+// GCC doesn't have thread safety attributes
+// UNSUPPORTED: gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -Wthread-safety
 
 // <shared_mutex>
 //
@@ -68,27 +67,27 @@ void f(std::chrono::time_point<std::chrono::steady_clock> tp, std::chrono::milli
   {
     m.lock_shared();
     read(data); // ok
-    ++data; // expected-error {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
+    ++data;     // expected-warning {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
     m.unlock_shared();
   }
   {
     if (m.try_lock_shared()) {
       read(data); // ok
-      ++data; // expected-error {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
+      ++data;     // expected-warning {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
       m.unlock_shared();
     }
   }
   {
     if (m.try_lock_shared_for(d)) {
       read(data); // ok
-      ++data; // expected-error {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
+      ++data;     // expected-warning {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
       m.unlock_shared();
     }
   }
   {
     if (m.try_lock_shared_until(tp)) {
       read(data); // ok
-      ++data; // expected-error {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
+      ++data;     // expected-warning {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
       m.unlock_shared();
     }
   }

diff  --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index c478d99fbed00..0cb81546665d4 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -134,11 +134,6 @@ def _mingwSupportsModules(cfg):
     Feature(name=lambda cfg: "msvc-{}".format(*_msvcVersion(cfg)), when=_isMSVC),
     Feature(name=lambda cfg: "msvc-{}.{}".format(*_msvcVersion(cfg)), when=_isMSVC),
 
-    Feature(
-        name="thread-safety",
-        when=lambda cfg: hasCompileFlag(cfg, "-Werror=thread-safety"),
-        actions=[AddCompileFlag("-Werror=thread-safety")],
-    ),
     Feature(
         name="diagnose-if-support",
         when=lambda cfg: hasCompileFlag(cfg, "-Wuser-defined-warnings"),


        


More information about the libcxx-commits mailing list