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 Fiseliervoid 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 Dionneint 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