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