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};
18
19static B *base;
20static B *threadbase;
21static unsigned cmask[THR];
22static unsigned dmask[THR];
23
24#pragma omp threadprivate(threadbase)
25
26B::B()
27{
28  assert (base == 0);
29}
30
31B::B(const B &b)
32{
33  unsigned index = &b - base;
34  assert (index < N);
35  cmask[omp_get_thread_num()] |= 1u << index;
36}
37
38B::~B()
39{
40  if (threadbase)
41    {
42      unsigned index = this - threadbase;
43      assert (index < N);
44      dmask[omp_get_thread_num()] |= 1u << index;
45    }
46}
47
48void foo()
49{
50  B b[N];
51
52  base = b;
53
54  #pragma omp parallel firstprivate(b)
55    {
56      assert (omp_get_num_threads () == THR);
57      threadbase = b;
58    }
59
60  threadbase = 0;
61}
62
63int main()
64{
65  omp_set_dynamic (0);
66  omp_set_num_threads (THR);
67  foo();
68
69  for (int i = 0; i < THR; ++i)
70    {
71      unsigned xmask = (1u << N) - 1;
72      assert (cmask[i] == xmask);
73      assert (dmask[i] == xmask);
74    }
75
76  return 0;
77}
78