1// { dg-do run }
2
3extern "C" void abort ();
4
5int cnt;
6
7int
8foo ()
9{
10  return cnt++;
11}
12
13template <typename T>
14void
15bar ()
16{
17  extern T x;
18  T v, *p;
19  #pragma omp atomic update
20    x = x + 7;
21  #pragma omp atomic
22    x = x + 7 + 6;
23  #pragma omp atomic update
24    x = x + 2 * 3;
25  #pragma omp atomic
26    x = x * (2 - 1);
27  #pragma omp atomic read
28    v = x;
29  if (v != 32)
30    abort ();
31  #pragma omp atomic write
32    x = 0;
33  #pragma omp atomic capture
34    {
35      v = x;
36      x = x | 1 ^ 2;
37    }
38  if (v != 0)
39    abort ();
40  #pragma omp atomic capture
41    {
42      v = x;
43      x = x | 4 | 2;
44    }
45  if (v != 3)
46    abort ();
47  #pragma omp atomic read
48    v = x;
49  if (v != 7)
50    abort ();
51  #pragma omp atomic capture
52    {
53      x = x ^ 6 & 2;
54      v = x;
55    }
56  if (v != 5)
57    abort ();
58  #pragma omp atomic capture
59    { x = x - (6 + 4); v = x; }
60  if (v != -5)
61    abort ();
62  #pragma omp atomic capture
63    { v = x; x = x - (1 | 2); }
64  if (v != -5)
65    abort ();
66  #pragma omp atomic read
67    v = x;
68  if (v != -8)
69    abort ();
70  #pragma omp atomic
71    x = x * -4 / 2;
72  #pragma omp atomic read
73    v = x;
74  if (v != 16)
75    abort ();
76  p = &x;
77  #pragma omp atomic update
78    p[foo (), 0] = p[foo (), 0] - 16;
79  #pragma omp atomic read
80    v = x;
81  if (cnt != 2 || v != 0)
82    abort ();
83  #pragma omp atomic capture
84    {
85      p[foo (), 0] += 6;
86      v = p[foo (), 0];
87    }
88  if (cnt != 4 || v != 6)
89    abort ();
90  #pragma omp atomic capture
91    {
92      v = p[foo (), 0];
93      p[foo (), 0] += 6;
94    }
95  if (cnt != 6 || v != 6)
96    abort ();
97  #pragma omp atomic read
98    v = x;
99  if (v != 12)
100    abort ();
101  #pragma omp atomic capture
102    {
103      p[foo (), 0] = p[foo (), 0] + 6;
104      v = p[foo (), 0];
105    }
106  if (cnt != 9 || v != 18)
107    abort ();
108  #pragma omp atomic capture
109    {
110      v = p[foo (), 0];
111      p[foo (), 0] = p[foo (), 0] + 6;
112    }
113  if (cnt != 12 || v != 18)
114    abort ();
115  #pragma omp atomic read
116    v = x;
117  if (v != 24)
118    abort ();
119  #pragma omp atomic capture
120  { v = p[foo (), 0]; p[foo (), 0]++; }
121  #pragma omp atomic capture
122  { v = p[foo (), 0]; ++p[foo (), 0]; }
123  #pragma omp atomic capture
124  { p[foo (), 0]++; v = p[foo (), 0]; }
125  #pragma omp atomic capture
126  { ++p[foo (), 0]; v = p[foo (), 0]; }
127  if (cnt != 20 || v != 28)
128    abort ();
129  #pragma omp atomic capture
130  { v = p[foo (), 0]; p[foo (), 0]--; }
131  #pragma omp atomic capture
132  { v = p[foo (), 0]; --p[foo (), 0]; }
133  #pragma omp atomic capture
134  { p[foo (), 0]--; v = p[foo (), 0]; }
135  #pragma omp atomic capture
136  { --p[foo (), 0]; v = p[foo (), 0]; }
137  if (cnt != 28 || v != 24)
138    abort ();
139}
140
141int x = 6;
142
143int
144main ()
145{
146  bar <int> ();
147  return 0;
148}
149