1 // { dg-do run }
2
3 extern "C" void abort ();
4
AA5 struct A { int a; A () : a (6) {} };
BB6 struct B { int b; B () : b (5) {} };
CC7 struct C { int c; C () : c (4) {} };
DD8 struct D { int d; D () : d (3) {} };
9 struct E : A, B {};
10 struct F : C, D {};
11 struct G : E, F {};
12 void foo (B &);
13 void foo (F &);
14 #pragma omp declare reduction (+:B:omp_out.b += omp_in.b) \
15 initializer(foo (omp_priv))
16
17 void
foo(B & x)18 foo (B &x)
19 {
20 if (x.b != 5)
21 abort ();
22 x.b = 9;
23 }
24
25 template <typename T>
bar(T & x,T & y,int z)26 void bar (T &x, T &y, int z)
27 {
28 if (z)
29 abort ();
30 x.a += y.a;
31 }
32
33 namespace N1
34 {
AA35 struct A { int a; A () : a (0) {} };
36 #pragma omp declare reduction (+:A:bar (omp_out, omp_in, 0))
37 };
38 namespace N2
39 {
40 struct B : N1::A { };
41 #pragma omp declare reduction (+:N1::A:bar (omp_out, omp_in, 1))
42 };
43
44 int
main()45 main ()
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