aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcxx/src/thread.cpp9
-rw-r--r--libcxx/test/libcxx/thread/thread.threads/create_late.pass.cpp29
2 files changed, 36 insertions, 2 deletions
diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp
index 0734659..ce2822d 100644
--- a/libcxx/src/thread.cpp
+++ b/libcxx/src/thread.cpp
@@ -115,8 +115,13 @@ sleep_for(const chrono::nanoseconds& ns)
__thread_specific_ptr<__thread_struct>&
__thread_local_data()
{
- static __thread_specific_ptr<__thread_struct> __p;
- return __p;
+ // Even though __thread_specific_ptr's destructor doesn't actually destroy
+ // anything (see comments there), we can't call it at all because threads may
+ // outlive the static variable and calling its destructor means accessing an
+ // object outside of its lifetime, which is UB.
+ alignas(__thread_specific_ptr<__thread_struct>) static char __b[sizeof(__thread_specific_ptr<__thread_struct>)];
+ static __thread_specific_ptr<__thread_struct>* __p = new (__b) __thread_specific_ptr<__thread_struct>();
+ return *__p;
}
// __thread_struct_imp
diff --git a/libcxx/test/libcxx/thread/thread.threads/create_late.pass.cpp b/libcxx/test/libcxx/thread/thread.threads/create_late.pass.cpp
new file mode 100644
index 0000000..8c1b6eb
--- /dev/null
+++ b/libcxx/test/libcxx/thread/thread.threads/create_late.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03
+
+#include "make_test_thread.h"
+
+void func() {}
+
+struct T {
+ ~T() {
+ // __thread_local_data is expected to be destroyed as it was created
+ // from the main(). Now trigger another access.
+ support::make_test_thread(func).join();
+ }
+} t;
+
+int main(int, char**) {
+ // Triggers construction of __thread_local_data.
+ support::make_test_thread(func).join();
+
+ return 0;
+}