13f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier//===-------------- thread_local_destruction_order.pass.cpp ---------------===//
23f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier//
33f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier//                     The LLVM Compiler Infrastructure
43f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier//
53f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
63f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier// Source Licenses. See LICENSE.TXT for details.
73f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier//
83f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier//===----------------------------------------------------------------------===//
93f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
10534295b102a7f9951ab2b8b38637b9cdf57cade1Shoaib Meenai// Darwin TLV finalization routines fail when creating a thread-local variable
11534295b102a7f9951ab2b8b38637b9cdf57cade1Shoaib Meenai// in the destructor for another thread-local variable:
12534295b102a7f9951ab2b8b38637b9cdf57cade1Shoaib Meenai// http://lists.llvm.org/pipermail/cfe-dev/2016-November/051376.html
13534295b102a7f9951ab2b8b38637b9cdf57cade1Shoaib Meenai// XFAIL: darwin
143f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier// UNSUPPORTED: c++98, c++03
1538488b9b2ce95cb9ee4765d334df25ffb183522aEric Fiselier// UNSUPPORTED: libcxxabi-no-threads
163f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
173f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier#include <cassert>
183f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier#include <thread>
193f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
203f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselierint seq = 0;
213f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
223f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselierclass OrderChecker {
233f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselierpublic:
243f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  explicit OrderChecker(int n) : n_{n} { }
253f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
263f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  ~OrderChecker() {
273f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier    assert(seq++ == n_);
283f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  }
293f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
303f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselierprivate:
313f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  int n_;
323f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier};
333f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
343f7b3700184b818c28ee085e3d629aa5f314169bEric Fiseliertemplate <int ID>
353f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselierclass CreatesThreadLocalInDestructor {
363f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselierpublic:
373f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  ~CreatesThreadLocalInDestructor() {
383f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier    thread_local OrderChecker checker{ID};
393f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  }
403f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier};
413f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
423f7b3700184b818c28ee085e3d629aa5f314169bEric FiselierOrderChecker global{7};
433f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
443f7b3700184b818c28ee085e3d629aa5f314169bEric Fiseliervoid thread_fn() {
453f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  static OrderChecker fn_static{5};
463f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
473f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  thread_local OrderChecker fn_thread_local{1};
483f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
493f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier}
503f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
513f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselierint main() {
523f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  static OrderChecker fn_static{6};
533f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
543f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  std::thread{thread_fn}.join();
553f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  assert(seq == 3);
563f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
573f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  thread_local OrderChecker fn_thread_local{4};
583f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  thread_local CreatesThreadLocalInDestructor<3> creates_tl;
593f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier
603f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier  return 0;
613f7b3700184b818c28ee085e3d629aa5f314169bEric Fiselier}
62