mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 19:08:21 +08:00
[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.
This commit is contained in:
@@ -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',
|
||||
]
|
||||
|
||||
@@ -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>`.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 @@ private:
|
||||
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;
|
||||
|
||||
@@ -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 @@ public:
|
||||
~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_; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,11 +134,6 @@ DEFAULT_FEATURES = [
|
||||
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"),
|
||||
|
||||
Reference in New Issue
Block a user