mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			89 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
| // { dg-do run }
 | |
| 
 | |
| extern "C" void abort ();
 | |
| 
 | |
| namespace NS
 | |
| {
 | |
|   struct U
 | |
|   {
 | |
|     void foo (U &, bool);
 | |
|     U ();
 | |
|   };
 | |
|   struct S
 | |
|   {
 | |
|     int s;
 | |
|     #pragma omp declare reduction (foo : U, S : omp_out.foo (omp_in, false))
 | |
|     #pragma omp declare reduction (foo : int : omp_out += omp_in) \
 | |
| 	initializer (omp_priv = int ())
 | |
|     void baz (int v)
 | |
|     {
 | |
|       S s;
 | |
|       int q = 0;
 | |
|       if (s.s != 6 || v != 0) abort ();
 | |
|       s.s = 20;
 | |
|       #pragma omp parallel num_threads (4) reduction (foo : s, v) \
 | |
| 	reduction (::NS::U::operator + : q)
 | |
|       {
 | |
| 	if (s.s != 6 || q != 0 || v != 0) abort ();
 | |
| 	asm volatile ("" : "+m" (s.s), "+r" (q), "+r" (v));
 | |
| 	s.s++; q++; v++;
 | |
|       }
 | |
|       if (s.s != 20 + q * 7 || q != v) abort ();
 | |
|     }
 | |
|     void foo (S &x) { s += x.s; }
 | |
|     void foo (S &x, bool y) { s += x.s; if (y) abort (); }
 | |
|     S (const S &x) { s = x.s + 1; }
 | |
|     S (const S &x, bool y) { s = x.s + 2; if (y) abort (); }
 | |
|     S () { s = 6; }
 | |
|     S (int x) { s = x; }
 | |
|     ~S ();
 | |
|   };
 | |
|   #pragma omp declare reduction (bar : S : omp_out.foo (omp_in)) \
 | |
| 	initializer (omp_priv (8))
 | |
| }
 | |
| 
 | |
| NS::S::~S ()
 | |
| {
 | |
|   if (s < 6) abort ();
 | |
|   s = -1;
 | |
|   /* Ensure the above store is not DSEd.  */
 | |
|   asm volatile ("" : : "r" (&s) : "memory");
 | |
| }
 | |
| 
 | |
| struct T : public NS::S
 | |
| {
 | |
|   void baz ()
 | |
|   {
 | |
|     S s;
 | |
|     int q = 0;
 | |
|     if (s.s != 6) abort ();
 | |
|     #pragma omp parallel num_threads (4) reduction (foo:s) \
 | |
| 	reduction (+: q)
 | |
|     {
 | |
|       if (s.s != 6 || q != 0) abort ();
 | |
|       asm volatile ("" : "+m" (s.s), "+r" (q));
 | |
|       s.s += 2; q++;
 | |
|     }
 | |
|     if (s.s != 6 + q * 8) abort ();
 | |
|   }
 | |
| };
 | |
| 
 | |
| int
 | |
| main ()
 | |
| {
 | |
|   NS::S s;
 | |
|   s.baz (0);
 | |
|   T t;
 | |
|   t.baz ();
 | |
|   int q = 0;
 | |
|   if (s.s != 6) abort ();
 | |
|   // Test ADL
 | |
|   #pragma omp parallel num_threads (4) reduction (bar:s) reduction (+:q)
 | |
|   {
 | |
|     if (s.s != 8 || q != 0) abort ();
 | |
|     asm volatile ("" : "+m" (s.s), "+r" (q));
 | |
|     s.s += 4; q++;
 | |
|   }
 | |
|   if (s.s != 6 + q * 12) abort ();
 | |
| }
 |