1*404b540aSrobert // { dg-do run }
2*404b540aSrobert // { dg-require-effective-target tls_runtime }
3*404b540aSrobert 
4*404b540aSrobert #include <omp.h>
5*404b540aSrobert #include <assert.h>
6*404b540aSrobert 
7*404b540aSrobert #define N 10
8*404b540aSrobert #define THR 4
9*404b540aSrobert 
10*404b540aSrobert struct B
11*404b540aSrobert {
12*404b540aSrobert   B();
13*404b540aSrobert   B(const B &);
14*404b540aSrobert   ~B();
15*404b540aSrobert   B& operator=(const B &);
16*404b540aSrobert   void doit();
17*404b540aSrobert };
18*404b540aSrobert 
19*404b540aSrobert static B *base;
20*404b540aSrobert static B *threadbase;
21*404b540aSrobert static unsigned cmask[THR];
22*404b540aSrobert static unsigned dmask[THR];
23*404b540aSrobert 
24*404b540aSrobert #pragma omp threadprivate(threadbase)
25*404b540aSrobert 
B()26*404b540aSrobert B::B()
27*404b540aSrobert {
28*404b540aSrobert   assert (base == 0);
29*404b540aSrobert }
30*404b540aSrobert 
B(const B & b)31*404b540aSrobert B::B(const B &b)
32*404b540aSrobert {
33*404b540aSrobert   unsigned index = &b - base;
34*404b540aSrobert   assert (index < N);
35*404b540aSrobert   cmask[omp_get_thread_num()] |= 1u << index;
36*404b540aSrobert }
37*404b540aSrobert 
~B()38*404b540aSrobert B::~B()
39*404b540aSrobert {
40*404b540aSrobert   if (threadbase)
41*404b540aSrobert     {
42*404b540aSrobert       unsigned index = this - threadbase;
43*404b540aSrobert       assert (index < N);
44*404b540aSrobert       dmask[omp_get_thread_num()] |= 1u << index;
45*404b540aSrobert     }
46*404b540aSrobert }
47*404b540aSrobert 
foo()48*404b540aSrobert void foo()
49*404b540aSrobert {
50*404b540aSrobert   B b[N];
51*404b540aSrobert 
52*404b540aSrobert   base = b;
53*404b540aSrobert 
54*404b540aSrobert   #pragma omp parallel firstprivate(b)
55*404b540aSrobert     {
56*404b540aSrobert       assert (omp_get_num_threads () == THR);
57*404b540aSrobert       threadbase = b;
58*404b540aSrobert     }
59*404b540aSrobert 
60*404b540aSrobert   threadbase = 0;
61*404b540aSrobert }
62*404b540aSrobert 
main()63*404b540aSrobert int main()
64*404b540aSrobert {
65*404b540aSrobert   omp_set_dynamic (0);
66*404b540aSrobert   omp_set_num_threads (THR);
67*404b540aSrobert   foo();
68*404b540aSrobert 
69*404b540aSrobert   for (int i = 0; i < THR; ++i)
70*404b540aSrobert     {
71*404b540aSrobert       unsigned xmask = (1u << N) - 1;
72*404b540aSrobert       assert (cmask[i] == xmask);
73*404b540aSrobert       assert (dmask[i] == xmask);
74*404b540aSrobert     }
75*404b540aSrobert 
76*404b540aSrobert   return 0;
77*404b540aSrobert }
78