1 // { dg-do run }
2 
3 #include <omp.h>
4 
5 int c, d, e;
RR6 struct R { R () {}; ~R () {}; int r; };
7 template <typename Q>
TT8 struct T { T () : t(d) {}; virtual ~T () {}; Q t; };
9 template <typename Q>
AA10 struct A : public R, virtual public T<Q> { A () : b(c), a(e) {} Q a; int &b; void m1 (); };
11 
12 void
take(int & a,int & b,int & c,int & d)13 take (int &a, int &b, int &c, int &d)
14 {
15   asm volatile ("" : : "g" (&a), "g" (&b), "g" (&c), "g" (&d) : "memory");
16 }
17 
18 template <typename Q>
19 void
m1()20 A<Q>::m1 ()
21 {
22   #pragma omp parallel private (a, r, T<Q>::t, A::b)
23   {
24     int q = omp_get_thread_num ();
25     a = q;
26     r = 2 * q;
27     T<Q>::t = 3 * q;
28     b = 4 * q;
29     take (a, r, T<Q>::t, b);
30     #pragma omp barrier
31     if (A::a != q || R::r != 2 * q || T<Q>::t != 3 * q || A::b != 4 * q)
32       __builtin_abort ();
33   }
34   a = 7;
35   r = 8;
36   T<Q>::t = 9;
37   b = 10;
38   #pragma omp parallel firstprivate (A::a, R::r, T<Q>::t, b)
39   {
40     int q = omp_get_thread_num ();
41     take (A::a, R::r, T<Q>::t, A::b);
42     if (a != 7 || r != 8 || T<Q>::t != 9 || b != 10)
43       __builtin_abort ();
44     A::a = 5 * q;
45     R::r = 6 * q;
46     T<Q>::t = 7 * q;
47     A::b = 8 * q;
48     take (a, r, T<Q>::t, b);
49     #pragma omp barrier
50     if (a != 5 * q || r != 6 * q || T<Q>::t != 7 * q || b != 8 * q)
51       __builtin_abort ();
52   }
53   bool f = false;
54   a = -5;
55   b = -4;
56   r = -3;
57   T<Q>::t = -2;
58   int n;
59   #pragma omp parallel for firstprivate (a, T<Q>::t, b, f) lastprivate (A::a, r, T<Q>::t, n)
60   for (int i = 0; i < omp_get_num_threads (); i++)
61     {
62       int q = omp_get_thread_num ();
63       if (!f)
64 	{
65 	  if (A::a != -5 || A::b != -4 || T<Q>::t != -2)
66 	    __builtin_abort ();
67 	}
68       else if (a != q || b != 2 * q || r != 3 * q || T<Q>::t != 4 * q)
69 	__builtin_abort ();
70       take (a, r, T<Q>::t, b);
71       A::a = q;
72       A::b = 2 * q;
73       R::r = 3 * q;
74       T<Q>::t = 4 * q;
75       n = q;
76       f = true;
77     }
78   if (a != n || r != 3 * n || T<Q>::t != 4 * n)
79     __builtin_abort ();
80   b = 8;
81   #pragma omp parallel
82     #pragma omp single
83       for (int i = 0; i < 5; i++)
84 	#pragma omp task firstprivate (T<Q>::t, b, n) private (a, R::r)
85 	  {
86 	    if (T<Q>::t != 4 * n || b != 8)
87 	      __builtin_abort ();
88 	    a = 9;
89 	    r = 8;
90 	    T<Q>::t = 12;
91 	    b = 18;
92 	    take (a, r, T<Q>::t, b);
93 	    if (a != 9 || r != 8 || T<Q>::t != 12 || b != 18)
94 	      __builtin_abort ();
95 	  }
96   a = 1;
97   b = 2;
98   R::r = 3;
99   T<Q>::t = 4;
100   #pragma omp parallel private (f)
101     {
102       f = false;
103     #pragma omp single
104     #pragma omp taskloop firstprivate (r, T<Q>::t, b, f) lastprivate (a, T<Q>::t, b, n)
105       for (int i = 0; i < 30; i++)
106 	{
107 	  int q = omp_get_thread_num ();
108 	  if (!f)
109 	    {
110 	      if (R::r != 3 || A::b != 2 || T<Q>::t != 4)
111 		__builtin_abort ();
112 	    }
113 	  else if (a != 7 * q || b != 8 * q || r != 9 * q || T<Q>::t != 10 * q)
114 	    __builtin_abort ();
115 	  take (a, r, T<Q>::t, b);
116 	  A::a = 7 * q;
117 	  A::b = 8 * q;
118 	  R::r = 9 * q;
119 	  T<Q>::t = 10 * q;
120 	  n = q;
121 	  f = true;
122 	}
123     }
124   if (a != 7 * n || b != 8 * n || T<Q>::t != 10 * n)
125     __builtin_abort ();
126   a = 1;
127   b = 2;
128   R::r = 3;
129   T<Q>::t = 4;
130   #pragma omp parallel private (f)
131     {
132       f = false;
133     #pragma omp single
134     #pragma omp taskloop firstprivate (r, T<Q>::t, b, A::a, f)
135       for (int i = 0; i < 30; i++)
136 	{
137 	  int q = omp_get_thread_num ();
138 	  if (!f)
139 	    {
140 	      if (A::a != 1 || R::r != 3 || A::b != 2 || T<Q>::t != 4)
141 		__builtin_abort ();
142 	    }
143 	  else if (a != 7 * q || b != 8 * q || r != 9 * q || T<Q>::t != 10 * q)
144 	    __builtin_abort ();
145 	  take (a, r, T<Q>::t, b);
146 	  A::a = 7 * q;
147 	  A::b = 8 * q;
148 	  R::r = 9 * q;
149 	  T<Q>::t = 10 * q;
150 	  f = true;
151 	}
152     }
153   #pragma omp parallel private (f)
154     {
155       f = false;
156     #pragma omp single
157     #pragma omp taskloop lastprivate (a, T<Q>::t, b, n) private (R::r)
158       for (int i = 0; i < 30; i++)
159 	{
160 	  int q = omp_get_thread_num ();
161 	  if (f && (a != 7 * q || b != 8 * q || r != 9 * q || T<Q>::t != 10 * q))
162 	    __builtin_abort ();
163 	  take (a, r, T<Q>::t, b);
164 	  A::a = 7 * q;
165 	  A::b = 8 * q;
166 	  R::r = 9 * q;
167 	  T<Q>::t = 10 * q;
168 	  n = q;
169 	  f = true;
170 	}
171     }
172   if (a != 7 * n || b != 8 * n || T<Q>::t != 10 * n)
173     __builtin_abort ();
174   #pragma omp parallel private (a, T<Q>::t, A::b, r)
175     {
176       int q = omp_get_thread_num ();
177       a = q;
178       b = 2 * q;
179       r = 3 * q;
180       T<Q>::t = 4 * q;
181       take (a, b, r, T<Q>::t);
182       #pragma omp single copyprivate (A::a, T<Q>::t, b, R::r)
183 	n = q;
184       if (a != n || b != 2 * n || r != 3 * n || T<Q>::t != 4 * n)
185 	__builtin_abort ();
186     }
187   a = 0;
188   b = 0;
189   R::r = 0;
190   T<Q>::t = 0;
191   #pragma omp parallel for reduction (+: A::a, T<Q>::t, b, R::r)
192   for (int i = 0; i < 30; i++)
193     {
194       a += i;
195       A::b += 2 * i;
196       r += 3 * i;
197       T<Q>::t += 4 * i;
198       take (a, b, r, T<Q>::t);
199     }
200   if (A::a != 435 || b != 2 * 435 || R::r != 3 * 435 || T<Q>::t != 4 * 435)
201     __builtin_abort ();
202 }
203 
204 int
main()205 main ()
206 {
207   A<int> a;
208   a.m1 ();
209   A<int &> b;
210   b.m1 ();
211 }
212