blob: 0bb359edffdb9ddd172f3d37c0a2037c1b68aa60 [file] [log] [blame]
Eric Fiselier3f7b3702016-10-12 08:54:10 +00001//===-------------- 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
Shoaib Meenai534295b2016-12-13 02:43:04 +000010// 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
Eric Fiselier3f7b3702016-10-12 08:54:10 +000014// UNSUPPORTED: c++98, c++03
Eric Fiselier38488b92016-10-14 09:12:53 +000015// UNSUPPORTED: libcxxabi-no-threads
Eric Fiselier3f7b3702016-10-12 08:54:10 +000016
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}