1// { dg-do run }
2
3#include <omp.h>
4#include <assert.h>
5
6struct B
7{
8  static int ccount;
9  static int dcount;
10  static int ecount;
11  static B *e_inner;
12  static B *e_outer;
13
14  B();
15  B(int);
16  B(const B &);
17  ~B();
18  B& operator=(const B &);
19  void doit();
20};
21
22int B::ccount;
23int B::dcount;
24int B::ecount;
25B * B::e_inner;
26B * B::e_outer;
27
28B::B(int)
29{
30  e_outer = this;
31}
32
33B::B(const B &b)
34{
35  assert (&b == e_outer);
36  #pragma omp atomic
37    ccount++;
38}
39
40B::~B()
41{
42  #pragma omp atomic
43    dcount++;
44}
45
46B& B::operator= (const B &b)
47{
48  assert (&b == e_inner);
49  assert (this == e_outer);
50  #pragma omp atomic
51    ecount++;
52  return *this;
53}
54
55void B::doit()
56{
57  #pragma omp critical
58    {
59      assert (e_inner == 0);
60      e_inner = this;
61    }
62}
63
64static int nthreads;
65
66void foo()
67{
68  B b(0);
69
70  #pragma omp parallel sections firstprivate(b) lastprivate(b)
71    {
72    #pragma omp section
73      nthreads = omp_get_num_threads ();
74    #pragma omp section
75      b.doit ();
76    }
77}
78
79int main()
80{
81  omp_set_dynamic (0);
82  omp_set_num_threads (4);
83  foo();
84
85  assert (B::ecount == 1);
86  assert (B::ccount == nthreads);
87  assert (B::dcount == nthreads+1);
88
89  return 0;
90}
91