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 20int seq = 0; 21 22class OrderChecker { 23public: 24 explicit OrderChecker(int n) : n_{n} { } 25 26 ~OrderChecker() { 27 assert(seq++ == n_); 28 } 29 30private: 31 int n_; 32}; 33 34template <int ID> 35class CreatesThreadLocalInDestructor { 36public: 37 ~CreatesThreadLocalInDestructor() { 38 thread_local OrderChecker checker{ID}; 39 } 40}; 41 42OrderChecker global{7}; 43 44void 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 51int 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