1 // PR middle-end/27337
2 // { dg-do run }
3 
4 #include <omp.h>
5 
6 extern "C" void abort (void);
7 
8 struct S
9 {
10   S ();
11   ~S ();
12   S (const S &);
13   int i;
14 };
15 
16 int n[3];
17 
18 S::S () : i(18)
19 {
20   if (omp_get_thread_num () != 0)
21 #pragma omp atomic
22     n[0]++;
23 }
24 
25 S::~S ()
26 {
27   if (omp_get_thread_num () != 0)
28 #pragma omp atomic
29     n[1]++;
30 }
31 
32 S::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 
42 S
43 foo ()
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 
56 S
57 bar ()
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 
70 S x;
71 
72 int
73 main (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