1// PR middle-end/27337
2// { dg-do run }
3
4#include <omp.h>
5
6extern "C" void abort (void);
7
8struct S
9{
10  S ();
11  ~S ();
12  S (const S &);
13  int i;
14};
15
16int n[3];
17
18S::S () : i(18)
19{
20  if (omp_get_thread_num () != 0)
21#pragma omp atomic
22    n[0]++;
23}
24
25S::~S ()
26{
27  if (omp_get_thread_num () != 0)
28#pragma omp atomic
29    n[1]++;
30}
31
32S::S (const S &x)
33{
34  if (x.i != 18)
35    abort ();
36  i = 118;
37  if (omp_get_thread_num () != 0)
38#pragma omp atomic
39    n[2]++;
40}
41
42S
43foo ()
44{
45  int i;
46  S ret;
47
48#pragma omp parallel for firstprivate (ret) lastprivate (ret) \
49			 schedule (static, 1) num_threads (4)
50  for (i = 0; i < 4; i++)
51    ret.i += omp_get_thread_num ();
52
53  return ret;
54}
55
56S
57bar ()
58{
59  int i;
60  S ret;
61
62#pragma omp parallel for num_threads (4)
63  for (i = 0; i < 4; i++)
64#pragma omp atomic
65    ret.i += omp_get_thread_num () + 1;
66
67  return ret;
68}
69
70S x;
71
72int
73main (void)
74{
75  omp_set_dynamic (false);
76  x = foo ();
77  if (n[0] != 0 || n[1] != 3 || n[2] != 3)
78    abort ();
79  if (x.i != 118 + 3)
80    abort ();
81  x = bar ();
82  if (n[0] != 0 || n[1] != 3 || n[2] != 3)
83    abort ();
84  if (x.i != 18 + 0 + 1 + 2 + 3 + 4)
85    abort ();
86  return 0;
87}
88