1202437Strasz// { dg-do run } 2202437Strasz 3202437Straszextern "C" void abort (); 4202437Strasz 5202437Strasznamespace NS 6202437Strasz{ 7202437Strasz struct U 8202437Strasz { 9202437Strasz void foo (U &, bool); 10202437Strasz U (); 11202437Strasz }; 12202437Strasz struct S 13202437Strasz { 14202437Strasz int s; 15202437Strasz #pragma omp declare reduction (foo : U, S : omp_out.foo (omp_in, false)) 16202437Strasz #pragma omp declare reduction (foo : int : omp_out += omp_in) \ 17202437Strasz initializer (omp_priv = int ()) 18202437Strasz void baz (int v) 19202437Strasz { 20202437Strasz S s; 21202437Strasz int q = 0; 22202437Strasz if (s.s != 6 || v != 0) abort (); 23202437Strasz s.s = 20; 24202437Strasz #pragma omp parallel num_threads (4) reduction (foo : s, v) \ 25202437Strasz reduction (::NS::U::operator + : q) 26202437Strasz { 27202437Strasz if (s.s != 6 || q != 0 || v != 0) abort (); 28202437Strasz asm volatile ("" : "+m" (s.s), "+r" (q), "+r" (v)); 29202437Strasz s.s++; q++; v++; 30202437Strasz } 31202437Strasz if (s.s != 20 + q * 7 || q != v) abort (); 32202437Strasz } 33202437Strasz void foo (S &x) { s += x.s; } 34202437Strasz void foo (S &x, bool y) { s += x.s; if (y) abort (); } 35202437Strasz S (const S &x) { s = x.s + 1; } 36202437Strasz S (const S &x, bool y) { s = x.s + 2; if (y) abort (); } 37202437Strasz S () { s = 6; } 38202437Strasz S (int x) { s = x; } 39230643Sattilio ~S (); 40223921Sae }; 41202437Strasz #pragma omp declare reduction (bar : S : omp_out.foo (omp_in)) \ 42202437Strasz initializer (omp_priv (8)) 43202437Strasz} 44202437Strasz 45202437StraszNS::S::~S () 46202437Strasz{ 47202437Strasz if (s < 6) abort (); 48202437Strasz s = -1; 49227309Sed /* Ensure the above store is not DSEd. */ 50202437Strasz asm volatile ("" : : "r" (&s) : "memory"); 51202437Strasz} 52202437Strasz 53202437Straszstruct T : public NS::S 54202437Strasz{ 55202437Strasz void baz () 56202437Strasz { 57202437Strasz S s; 58202437Strasz int q = 0; 59202437Strasz if (s.s != 6) abort (); 60202437Strasz #pragma omp parallel num_threads (4) reduction (foo:s) \ 61202437Strasz reduction (+: q) 62238218Strasz { 63202437Strasz if (s.s != 6 || q != 0) abort (); 64202437Strasz asm volatile ("" : "+m" (s.s), "+r" (q)); 65202437Strasz s.s += 2; q++; 66202437Strasz } 67202437Strasz if (s.s != 6 + q * 8) abort (); 68202437Strasz } 69202437Strasz}; 70202437Strasz 71202437Straszint 72202437Straszmain () 73202437Strasz{ 74202437Strasz NS::S s; 75202437Strasz s.baz (0); 76202437Strasz T t; 77202437Strasz t.baz (); 78202437Strasz int q = 0; 79202437Strasz if (s.s != 6) abort (); 80202437Strasz // Test ADL 81202437Strasz #pragma omp parallel num_threads (4) reduction (bar:s) reduction (+:q) 82202437Strasz { 83202437Strasz if (s.s != 8 || q != 0) abort (); 84202437Strasz asm volatile ("" : "+m" (s.s), "+r" (q)); 85202437Strasz s.s += 4; q++; 86202437Strasz } 87202437Strasz if (s.s != 6 + q * 12) abort (); 88202437Strasz} 89202437Strasz