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