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& operator=(const B &);
13};
14
15static B *base;
16static B *threadbase;
17static int singlethread;
18#pragma omp threadprivate(threadbase)
19
20static unsigned cmask[THR];
21
22B& B::operator= (const B &b)
23{
24  unsigned sindex = &b - base;
25  unsigned tindex = this - threadbase;
26  assert(sindex < N);
27  assert(sindex == tindex);
28  cmask[omp_get_thread_num ()] |= 1u << tindex;
29  return *this;
30}
31
32void foo()
33{
34  #pragma omp parallel
35    {
36      B b[N];
37      threadbase = b;
38      #pragma omp single copyprivate(b)
39	{
40	  assert(omp_get_num_threads () == THR);
41	  singlethread = omp_get_thread_num ();
42	  base = b;
43	}
44    }
45}
46
47int main()
48{
49  omp_set_dynamic (0);
50  omp_set_num_threads (THR);
51  foo();
52
53  for (int i = 0; i < THR; ++i)
54    if (i == singlethread)
55      assert(cmask[singlethread] == 0);
56    else
57      assert(cmask[i] == (1u << N) - 1);
58
59  return 0;
60}
61