1 //===-------------- thread_local_destruction_order.pass.cpp ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // Darwin TLV finalization routines fail when creating a thread-local variable 11 // in the destructor for another thread-local variable: 12 // http://lists.llvm.org/pipermail/cfe-dev/2016-November/051376.html 13 // XFAIL: darwin 14 // UNSUPPORTED: c++98, c++03 15 // UNSUPPORTED: libcxxabi-no-threads 16 17 #include <cassert> 18 #include <thread> 19 20 int seq = 0; 21 22 class OrderChecker { 23 public: 24 explicit OrderChecker(int n) : n_{n} { } 25 26 ~OrderChecker() { 27 assert(seq++ == n_); 28 } 29 30 private: 31 int n_; 32 }; 33 34 template <int ID> 35 class CreatesThreadLocalInDestructor { 36 public: 37 ~CreatesThreadLocalInDestructor() { 38 thread_local OrderChecker checker{ID}; 39 } 40 }; 41 42 OrderChecker global{7}; 43 44 void thread_fn() { 45 static OrderChecker fn_static{5}; 46 thread_local CreatesThreadLocalInDestructor<2> creates_tl2; 47 thread_local OrderChecker fn_thread_local{1}; 48 thread_local CreatesThreadLocalInDestructor<0> creates_tl0; 49 } 50 51 int main() { 52 static OrderChecker fn_static{6}; 53 54 std::thread{thread_fn}.join(); 55 assert(seq == 3); 56 57 thread_local OrderChecker fn_thread_local{4}; 58 thread_local CreatesThreadLocalInDestructor<3> creates_tl; 59 60 return 0; 61 } 62