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