1 //===-------------- thread_local_destruction_order.pass.cpp ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // Darwin TLV finalization routines used to fail when creating a thread-local 10 // variable in the destructor for another thread-local variable: 11 // - http://lists.llvm.org/pipermail/cfe-dev/2016-November/051376.html 12 // - rdar://29523281 13 // This was fixed in dyld in macos 10.15. 14 // 15 // XFAIL: macosx10.14 16 // XFAIL: macosx10.13 17 // XFAIL: macosx10.12 18 // XFAIL: macosx10.11 19 // XFAIL: macosx10.10 20 // XFAIL: macosx10.9 21 22 // UNSUPPORTED: c++03 23 // UNSUPPORTED: libcxxabi-no-threads 24 25 #include <cassert> 26 #include <thread> 27 28 #include "make_test_thread.h" 29 30 int seq = 0; 31 32 class OrderChecker { 33 public: OrderChecker(int n)34 explicit OrderChecker(int n) : n_{n} { } 35 ~OrderChecker()36 ~OrderChecker() { 37 assert(seq++ == n_); 38 } 39 40 private: 41 int n_; 42 }; 43 44 template <int ID> 45 class CreatesThreadLocalInDestructor { 46 public: ~CreatesThreadLocalInDestructor()47 ~CreatesThreadLocalInDestructor() { 48 thread_local OrderChecker checker{ID}; 49 } 50 }; 51 52 OrderChecker global{7}; 53 thread_fn()54void thread_fn() { 55 static OrderChecker fn_static{5}; 56 thread_local CreatesThreadLocalInDestructor<2> creates_tl2; 57 thread_local OrderChecker fn_thread_local{1}; 58 thread_local CreatesThreadLocalInDestructor<0> creates_tl0; 59 } 60 main(int,char **)61int main(int, char**) { 62 static OrderChecker fn_static{6}; 63 64 support::make_test_thread(thread_fn).join(); 65 assert(seq == 3); 66 67 thread_local OrderChecker fn_thread_local{4}; 68 thread_local CreatesThreadLocalInDestructor<3> creates_tl; 69 70 return 0; 71 } 72