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