1100966Siwasaki// { dg-do run }
2100966Siwasaki
3100966Siwasaki#include <omp.h>
4100966Siwasaki#include <assert.h>
5100966Siwasaki
6100966Siwasakistruct B
7217365Sjkim{
8306536Sjkim  static int ccount;
9100966Siwasaki  static int dcount;
10100966Siwasaki  static int ecount;
11217365Sjkim  static B *e_inner;
12217365Sjkim  static B *e_outer;
13217365Sjkim
14217365Sjkim  B();
15217365Sjkim  B(int);
16217365Sjkim  B(const B &);
17217365Sjkim  ~B();
18217365Sjkim  B& operator=(const B &);
19217365Sjkim  void doit();
20217365Sjkim};
21217365Sjkim
22217365Sjkimint B::ccount;
23217365Sjkimint B::dcount;
24217365Sjkimint B::ecount;
25100966SiwasakiB * B::e_inner;
26217365SjkimB * B::e_outer;
27217365Sjkim
28217365SjkimB::B(int)
29100966Siwasaki{
30217365Sjkim  e_outer = this;
31217365Sjkim}
32217365Sjkim
33217365SjkimB::B(const B &b)
34217365Sjkim{
35217365Sjkim  assert (&b == e_outer);
36217365Sjkim  #pragma omp atomic
37217365Sjkim    ccount++;
38217365Sjkim}
39217365Sjkim
40217365SjkimB::~B()
41217365Sjkim{
42217365Sjkim  #pragma omp atomic
43100966Siwasaki    dcount++;
44193341Sjkim}
45193341Sjkim
46193341SjkimB& B::operator= (const B &b)
47100966Siwasaki{
48100966Siwasaki  assert (&b == e_inner);
49102550Siwasaki  assert (this == e_outer);
50100966Siwasaki  #pragma omp atomic
51100966Siwasaki    ecount++;
52100966Siwasaki  return *this;
53100966Siwasaki}
54100966Siwasaki
55100966Siwasakivoid B::doit()
56100966Siwasaki{
57281075Sdim  #pragma omp critical
58281075Sdim    {
59100966Siwasaki      assert (e_inner == 0);
60100966Siwasaki      e_inner = this;
61100966Siwasaki    }
62100966Siwasaki}
63100966Siwasaki
64151937Sjkimstatic int nthreads;
65100966Siwasaki
66100966Siwasakivoid foo()
67100966Siwasaki{
68100966Siwasaki  B b(0);
69100966Siwasaki
70281075Sdim  #pragma omp parallel sections firstprivate(b) lastprivate(b)
71151937Sjkim    {
72100966Siwasaki    #pragma omp section
73100966Siwasaki      nthreads = omp_get_num_threads ();
74100966Siwasaki    #pragma omp section
75100966Siwasaki      b.doit ();
76100966Siwasaki    }
77100966Siwasaki}
78243347Sjkim
79100966Siwasakiint main()
80151937Sjkim{
81151937Sjkim  omp_set_dynamic (0);
82100966Siwasaki  omp_set_num_threads (4);
83100966Siwasaki  foo();
84167802Sjkim
85243347Sjkim  assert (B::ecount == 1);
86243347Sjkim  assert (B::ccount == nthreads);
87243347Sjkim  assert (B::dcount == nthreads+1);
88100966Siwasaki
89167802Sjkim  return 0;
90167802Sjkim}
91167802Sjkim