Home | History | Annotate | Download | only in test
      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