2016-10-12 16:54:10 +08:00
|
|
|
//===-------------- thread_local_destruction_order.pass.cpp ---------------===//
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-12-13 10:43:04 +08:00
|
|
|
// Darwin TLV finalization routines fail when creating a thread-local variable
|
|
|
|
// in the destructor for another thread-local variable:
|
|
|
|
// http://lists.llvm.org/pipermail/cfe-dev/2016-November/051376.html
|
|
|
|
// XFAIL: darwin
|
2016-10-12 16:54:10 +08:00
|
|
|
// UNSUPPORTED: c++98, c++03
|
2016-10-14 17:12:53 +08:00
|
|
|
// UNSUPPORTED: libcxxabi-no-threads
|
2016-10-12 16:54:10 +08:00
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
int seq = 0;
|
|
|
|
|
|
|
|
class OrderChecker {
|
|
|
|
public:
|
|
|
|
explicit OrderChecker(int n) : n_{n} { }
|
|
|
|
|
|
|
|
~OrderChecker() {
|
|
|
|
assert(seq++ == n_);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int n_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <int ID>
|
|
|
|
class CreatesThreadLocalInDestructor {
|
|
|
|
public:
|
|
|
|
~CreatesThreadLocalInDestructor() {
|
|
|
|
thread_local OrderChecker checker{ID};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
OrderChecker global{7};
|
|
|
|
|
|
|
|
void thread_fn() {
|
|
|
|
static OrderChecker fn_static{5};
|
|
|
|
thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
|
|
|
|
thread_local OrderChecker fn_thread_local{1};
|
|
|
|
thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
static OrderChecker fn_static{6};
|
|
|
|
|
|
|
|
std::thread{thread_fn}.join();
|
|
|
|
assert(seq == 3);
|
|
|
|
|
|
|
|
thread_local OrderChecker fn_thread_local{4};
|
|
|
|
thread_local CreatesThreadLocalInDestructor<3> creates_tl;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|