xref: /llvm-project/libcxxabi/test/thread_local_destruction_order.pass.cpp (revision 7f00b2aa75f0f090c37bf9d5ccb55fca15c35538)
1eb8650a7SLouis Dionne //===----------------------------------------------------------------------===//
2829c0eabSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6829c0eabSEric Fiselier //
7829c0eabSEric Fiselier //===----------------------------------------------------------------------===//
8829c0eabSEric Fiselier 
931cbe0f2SLouis Dionne // UNSUPPORTED: c++03
10a7f9895cSLouis Dionne // UNSUPPORTED: no-threads
11829c0eabSEric Fiselier 
127ec6c629SEd Maste // XFAIL: LIBCXX-FREEBSD-FIXME
137ec6c629SEd Maste 
14*7f00b2aaSMartin Storsjö // TODO: This test does start working with newer updates of the mingw-w64
15*7f00b2aaSMartin Storsjö // toolchain, when it includes the following commit:
16*7f00b2aaSMartin Storsjö // https://github.com/mingw-w64/mingw-w64/commit/71eddccd746c56d9cde28bb5620d027d49259de9
17*7f00b2aaSMartin Storsjö // Thus, remove this UNSUPPORTED marking after the next update of the CI
18*7f00b2aaSMartin Storsjö // toolchain.
19*7f00b2aaSMartin Storsjö // UNSUPPORTED: target={{.*-windows-gnu}}
20*7f00b2aaSMartin Storsjö 
21829c0eabSEric Fiselier #include <cassert>
22829c0eabSEric Fiselier #include <thread>
23829c0eabSEric Fiselier 
2456462801SLouis Dionne #include "make_test_thread.h"
2556462801SLouis Dionne 
26829c0eabSEric Fiselier int seq = 0;
27829c0eabSEric Fiselier 
28829c0eabSEric Fiselier class OrderChecker {
29829c0eabSEric Fiselier public:
OrderChecker(int n)30829c0eabSEric Fiselier   explicit OrderChecker(int n) : n_{n} { }
31829c0eabSEric Fiselier 
~OrderChecker()32829c0eabSEric Fiselier   ~OrderChecker() {
33829c0eabSEric Fiselier     assert(seq++ == n_);
34829c0eabSEric Fiselier   }
35829c0eabSEric Fiselier 
36829c0eabSEric Fiselier private:
37829c0eabSEric Fiselier   int n_;
38829c0eabSEric Fiselier };
39829c0eabSEric Fiselier 
40829c0eabSEric Fiselier template <int ID>
41829c0eabSEric Fiselier class CreatesThreadLocalInDestructor {
42829c0eabSEric Fiselier public:
~CreatesThreadLocalInDestructor()43829c0eabSEric Fiselier   ~CreatesThreadLocalInDestructor() {
44829c0eabSEric Fiselier     thread_local OrderChecker checker{ID};
45829c0eabSEric Fiselier   }
46829c0eabSEric Fiselier };
47829c0eabSEric Fiselier 
48829c0eabSEric Fiselier OrderChecker global{7};
49829c0eabSEric Fiselier 
thread_fn()50829c0eabSEric Fiselier void thread_fn() {
51829c0eabSEric Fiselier   static OrderChecker fn_static{5};
52829c0eabSEric Fiselier   thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
53829c0eabSEric Fiselier   thread_local OrderChecker fn_thread_local{1};
54829c0eabSEric Fiselier   thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
55829c0eabSEric Fiselier }
56829c0eabSEric Fiselier 
main(int,char **)57504bc07dSLouis Dionne int main(int, char**) {
58829c0eabSEric Fiselier   static OrderChecker fn_static{6};
59829c0eabSEric Fiselier 
6056462801SLouis Dionne   support::make_test_thread(thread_fn).join();
61829c0eabSEric Fiselier   assert(seq == 3);
62829c0eabSEric Fiselier 
63829c0eabSEric Fiselier   thread_local OrderChecker fn_thread_local{4};
64829c0eabSEric Fiselier   thread_local CreatesThreadLocalInDestructor<3> creates_tl;
65829c0eabSEric Fiselier 
66829c0eabSEric Fiselier   return 0;
67829c0eabSEric Fiselier }
68