1 // PR c++/93931
2 // { dg-do run }
3 // { dg-options "-O2 -std=c++14" }
4 
5 extern "C" void abort ();
6 
7 void
sink(int & x)8 sink (int &x)
9 {
10   int *volatile p;
11   p = &x;
12   (*p)++;
13 }
14 
15 int
foo()16 foo ()
17 {
18   int r = 0;
19   [&r] () {
20 #pragma omp parallel for reduction(+ : r)
21     for (int i = 0; i < 1024; ++i)
22       r += i;
23   } ();
24   return r;
25 }
26 
27 int
bar()28 bar ()
29 {
30   int l = 0;
31   [&l] () {
32 #pragma omp parallel for lastprivate (l)
33     for (int i = 0; i < 1024; ++i)
34       l = i;
35   } ();
36   return l;
37 }
38 
39 void
baz()40 baz ()
41 {
42   int f = 18;
43   [&f] () {
44 #pragma omp parallel for firstprivate (f)
45     for (int i = 0; i < 1024; ++i)
46       {
47 	sink (f);
48 	f += 3;
49 	sink (f);
50 	if (f != 23)
51 	  abort ();
52 	sink (f);
53 	f -= 7;
54 	sink (f);
55       }
56   } ();
57   if (f != 18)
58     abort ();
59 }
60 
61 int
qux()62 qux ()
63 {
64   int r = 0;
65   [&] () {
66 #pragma omp parallel for reduction(+ : r)
67     for (int i = 0; i < 1024; ++i)
68       r += i;
69   } ();
70   return r;
71 }
72 
73 int
corge()74 corge ()
75 {
76   int l = 0;
77   [&] () {
78 #pragma omp parallel for lastprivate (l)
79     for (int i = 0; i < 1024; ++i)
80       l = i;
81   } ();
82   return l;
83 }
84 
85 void
garply()86 garply ()
87 {
88   int f = 18;
89   [&] () {
90 #pragma omp parallel for firstprivate (f)
91     for (int i = 0; i < 1024; ++i)
92       {
93 	sink (f);
94 	f += 3;
95 	sink (f);
96 	if (f != 23)
97 	  abort ();
98 	sink (f);
99 	f -= 7;
100 	sink (f);
101       }
102   } ();
103   if (f != 18)
104     abort ();
105 }
106 
107 int
main()108 main ()
109 {
110   if (foo () != 1024 * 1023 / 2)
111     abort ();
112   if (bar () != 1023)
113     abort ();
114   baz ();
115   if (qux () != 1024 * 1023 / 2)
116     abort ();
117   if (corge () != 1023)
118     abort ();
119   garply ();
120 }
121