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, T<Q>::t) shared (r, A::b) default(none)
23 {
24 int q = omp_get_thread_num (), q2;
25 a = q;
26 T<Q>::t = 3 * q;
27 #pragma omp single copyprivate (q2)
28 {
29 r = 2 * q;
30 b = 4 * q;
31 q2 = q;
32 }
33 take (a, r, T<Q>::t, b);
34 #pragma omp barrier
35 if (A::a != q || R::r != 2 * q2 || T<Q>::t != 3 * q || A::b != 4 * q2)
36 __builtin_abort ();
37 }
38 a = 7;
39 r = 8;
40 T<Q>::t = 9;
41 b = 10;
42 #pragma omp parallel shared (A::a) default (none) firstprivate (R::r, b) shared (T<Q>::t)
43 {
44 int q = omp_get_thread_num (), q2;
45 take (A::a, R::r, T<Q>::t, A::b);
46 if (a != 7 || r != 8 || T<Q>::t != 9 || b != 10)
47 __builtin_abort ();
48 R::r = 6 * q;
49 #pragma omp barrier
50 #pragma omp single copyprivate (q2)
51 {
52 A::a = 5 * q;
53 T<Q>::t = 7 * q;
54 q2 = q;
55 }
56 A::b = 8 * q;
57 take (a, r, T<Q>::t, b);
58 #pragma omp barrier
59 if (a != 5 * q2 || r != 6 * q || T<Q>::t != 7 * q2 || b != 8 * q)
60 __builtin_abort ();
61 }
62 a = 1;
63 b = 2;
64 R::r = 3;
65 T<Q>::t = 4;
66 bool f = false;
67 #pragma omp parallel private (f)
68 {
69 f = false;
70 #pragma omp single
71 #pragma omp taskloop default(none) firstprivate (r, A::a, f) shared (T<Q>::t, b)
72 for (int i = 0; i < 30; i++)
73 {
74 int q = omp_get_thread_num ();
75 int tv, bv;
76 #pragma omp atomic read
77 tv = T<Q>::t;
78 #pragma omp atomic read
79 bv = A::b;
80 if (i == 16)
81 {
82 if (bv != 2 || tv != 4)
83 __builtin_abort ();
84 }
85 else
86 {
87 if ((bv != 2 && bv != 8) || (tv != 4 && tv != 9))
88 __builtin_abort ();
89 }
90 if (!f)
91 {
92 if (A::a != 1 || R::r != 3)
93 __builtin_abort ();
94 }
95 else if (a != 7 * q || r != 9 * q)
96 __builtin_abort ();
97 take (a, r, T<Q>::t, b);
98 A::a = 7 * q;
99 R::r = 9 * q;
100 if (i == 16)
101 {
102 #pragma omp atomic write
103 A::b = 8;
104 #pragma omp atomic write
105 T<Q>::t = 9;
106 }
107 f = true;
108 }
109 }
110 }
111
112 int
main()113 main ()
114 {
115 A<int> a;
116 a.m1 ();
117 A<int &> b;
118 b.m1 ();
119 }
120