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 
10 struct B
11 {
12   B& operator=(const B &);
13 };
14 
15 static B *base;
16 static B *threadbase;
17 static int singlethread;
18 #pragma omp threadprivate(threadbase)
19 
20 static unsigned cmask[THR];
21 
22 B& 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 
foo()32 void 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 
main()47 int 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