1// { dg-do run } 2 3extern "C" void abort (); 4 5struct A { int a; A () : a (6) {} }; 6struct B { int b; B () : b (5) {} }; 7struct C { int c; C () : c (4) {} }; 8struct D { int d; D () : d (3) {} }; 9struct E : A, B {}; 10struct F : C, D {}; 11struct G : E, F {}; 12void foo (B &); 13void foo (F &); 14#pragma omp declare reduction (+:B:omp_out.b += omp_in.b) \ 15 initializer(foo (omp_priv)) 16 17void 18foo (B &x) 19{ 20 if (x.b != 5) 21 abort (); 22 x.b = 9; 23} 24 25template <typename T> 26void bar (T &x, T &y, int z) 27{ 28 if (z) 29 abort (); 30 x.a += y.a; 31} 32 33namespace N1 34{ 35 struct A { int a; A () : a (0) {} }; 36 #pragma omp declare reduction (+:A:bar (omp_out, omp_in, 0)) 37}; 38namespace N2 39{ 40 struct B : N1::A { }; 41 #pragma omp declare reduction (+:N1::A:bar (omp_out, omp_in, 1)) 42}; 43 44int 45main () 46{ 47 G g; 48 int i = 0; 49 #pragma omp parallel reduction(+:g, i) 50 { 51 if (g.a != 6 || g.b != 9 || g.c != 4 || g.d != 3) 52 abort (); 53 g.a = 1, g.b = 2, g.c = 3, g.d = 4, i = 1; 54 } 55 if (g.a != 6 || g.b != 5 + 2 * i || g.c != 4 || g.d != 3) 56 abort (); 57 N2::B b; 58 i = 0; 59 #pragma omp parallel reduction (+:b, i) 60 { 61 if (b.a != 0) 62 abort (); 63 b.a = 4; 64 i = 1; 65 } 66 if (b.a != 4 * i) 67 abort (); 68} 69