lhchavez created this revision.
Herald added a reviewer: EricWF.
Herald added a subscriber: cfe-commits.

This adds clang negative thread safery assertion support to std::mutex,
as documented in:

https://clang.llvm.org/docs/ThreadSafetyAnalysis.html

Fixes #34951.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41498

Files:
  include/__mutex_base
  test/libcxx/thread/thread.mutex/thread_safety_annotations_negative.fail.cpp
  test/libcxx/thread/thread.mutex/thread_safety_annotations_negative.pass.cpp
  utils/libcxx/test/config.py

Index: utils/libcxx/test/config.py
===================================================================
--- utils/libcxx/test/config.py
+++ utils/libcxx/test/config.py
@@ -135,6 +135,7 @@
         self.configure_cxx_library_root()
         self.configure_use_clang_verify()
         self.configure_use_thread_safety()
+        self.configure_use_thread_safety_negative()
         self.configure_execute_external()
         self.configure_ccache()
         self.configure_compile_flags()
@@ -354,6 +355,15 @@
             self.config.available_features.add('thread-safety')
             self.lit_config.note("enabling thread-safety annotations")
 
+    def configure_use_thread_safety_negative(self):
+        '''If set, run clang with -verify on failing tests.'''
+        has_thread_safety_negative = self.cxx.hasCompileFlag(
+            '-Werror=thread-safety-negative')
+        if has_thread_safety_negative:
+            self.cxx.compile_flags += ['-Werror=thread-safety-negative']
+            self.config.available_features.add('thread-safety-negative')
+            self.lit_config.note("enabling thread-safety-negative annotations")
+
     def configure_execute_external(self):
         # Choose between lit's internal shell pipeline runner and a real shell.
         # If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the
Index: test/libcxx/thread/thread.mutex/thread_safety_annotations_negative.pass.cpp
===================================================================
--- /dev/null
+++ test/libcxx/thread/thread.mutex/thread_safety_annotations_negative.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: thread-safety, thread-safety-negative
+
+// <mutex>
+
+#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+
+#include <mutex>
+
+std::mutex m;
+int foo __attribute__((guarded_by(m)));
+
+void increment() __attribute__((requires_capability(!m))) {
+  m.lock();
+  foo++;
+  m.unlock();
+}
+
+int main() {
+  increment();
+}
Index: test/libcxx/thread/thread.mutex/thread_safety_annotations_negative.fail.cpp
===================================================================
--- /dev/null
+++ test/libcxx/thread/thread.mutex/thread_safety_annotations_negative.fail.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: thread-safety, thread-safety-negative
+
+// <mutex>
+
+#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+
+#include <mutex>
+
+std::mutex m;
+int foo __attribute__((guarded_by(m)));
+
+void increment() __attribute__((requires_capability(!m))) {
+  m.lock();
+  foo++;
+  m.unlock();
+}
+
+int main() {
+  m.lock();
+  increment();
+  m.unlock();
+}
Index: include/__mutex_base
===================================================================
--- include/__mutex_base
+++ include/__mutex_base
@@ -62,6 +62,9 @@
     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());
+#ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
+    const mutex& operator!() const { return *this; }
+#endif
 
     typedef __libcpp_mutex_t* native_handle_type;
     _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D41498: [libc... Luis Héctor Chávez via Phabricator via cfe-commits

Reply via email to