1 // { dg-do compile } 2 // { dg-options "-fopenmp" } 3 SS4struct S { int s; S () : s (0) {} S (int x) : s (x) {} ~S () {} }; TT5struct T { int t; T () : t (0) {} T (int x) : t (x) {} ~T () {} }; 6 7 #pragma omp declare reduction (+: ::S: omp_out.s += omp_in.s) 8 #pragma omp declare reduction (*: S: omp_out.s *= omp_in.s) \ 9 initializer (omp_priv (1)) 10 #pragma omp declare reduction (foo: S: omp_out.s += omp_in.s) 11 12 void f1()13f1 () 14 { 15 S s, s2; 16 T t; 17 #pragma omp declare reduction (+: T: omp_out.t += omp_in.t) 18 #pragma omp parallel reduction (+: t) reduction (foo: s) reduction (*: s2) 19 s.s = 1, t.t = 1, s2.s = 2; 20 #pragma omp parallel reduction (::operator +: s) 21 s.s = 1; 22 #pragma omp parallel reduction (+: s) 23 s.s = 1; 24 } 25 26 template <int N> 27 int f2()28f2 () 29 { 30 S s, s2; 31 T t; 32 #pragma omp declare reduction (+: T: omp_out.t += omp_in.t) 33 #pragma omp parallel reduction (+: t) reduction (foo: s) reduction (*: s2) 34 s.s = 1, t.t = 1, s2.s = 2; 35 #pragma omp parallel reduction (::operator +: s) 36 s.s = 1; 37 #pragma omp parallel reduction (+: s) 38 s.s = 1; 39 return 0; 40 } 41 42 int x = f2<0> (); 43 44 void bar (S &); 45 46 void f3()47f3 () 48 { 49 #pragma omp declare reduction (foo: S: omp_out.s += omp_in.s) initializer (bar (omp_priv)) 50 #pragma omp declare reduction (bar: S: omp_out.s += omp_in.s) initializer (bar (omp_orig)) // { dg-error "one of the initializer call arguments should be" } 51 } 52 53 template <typename T> 54 int f4()55f4 () 56 { 57 #pragma omp declare reduction (foo: T: omp_out.s += omp_in.s) initializer (bar (omp_priv)) 58 #pragma omp declare reduction (bar: T: omp_out.s += omp_in.s) initializer (bar (omp_orig)) // { dg-error "one of the initializer call arguments should be" } 59 return 0; 60 } 61 62 int y = f4 <S> (); 63 64 namespace N1 65 { 66 #pragma omp declare reduction (+: ::S: omp_out.s *= omp_in.s) // { dg-message "previous" } 67 #pragma omp declare reduction (+: S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" } 68 void f5()69 f5 () 70 { 71 #pragma omp declare reduction (f5: S: omp_out.s *= omp_in.s) // { dg-message "previous" } 72 #pragma omp declare reduction (f5: ::S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" } 73 } 74 } 75 76 namespace N2 77 { 78 struct U 79 { 80 #pragma omp declare reduction (bar: S: omp_out.s *= omp_in.s) // { dg-message "previous" } 81 #pragma omp declare reduction (bar: S: omp_out.s += omp_in.s) // { dg-error "cannot be overloaded" } 82 }; 83 } 84 85 namespace N3 86 { 87 #pragma omp declare reduction (+: ::S: omp_out.s *= omp_in.s) // { dg-message "previous" } 88 #pragma omp declare reduction (+: T: omp_out.t += omp_in.t) 89 #pragma omp declare reduction (+: S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" } 90 #pragma omp declare reduction (n3: long: omp_out += omp_in) // { dg-message "previous" } 91 #pragma omp declare reduction (n3: long int: omp_out += omp_in) // { dg-error "redeclaration of" } 92 #pragma omp declare reduction (n3: short unsigned: omp_out += omp_in) 93 #pragma omp declare reduction (n3: short int: omp_out += omp_in) 94 void f6()95 f6 () 96 { 97 #pragma omp declare reduction (f6: T: omp_out.t += omp_in.t) 98 #pragma omp declare reduction (f6: S: omp_out.s *= omp_in.s) // { dg-message "previous" } 99 #pragma omp declare reduction (f6: ::S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" } 100 #pragma omp declare reduction (f6: long: omp_out += omp_in) // { dg-message "previous" } 101 #pragma omp declare reduction (f6: long int: omp_out += omp_in) // { dg-error "redeclaration of" } 102 #pragma omp declare reduction (f6: short unsigned: omp_out += omp_in) 103 #pragma omp declare reduction (f6: short int: omp_out += omp_in) 104 } 105 } 106 107 namespace N4 108 { 109 struct U 110 { 111 #pragma omp declare reduction (bar: T: omp_out.t += omp_in.t) 112 #pragma omp declare reduction (bar: S: omp_out.s *= omp_in.s) // { dg-message "previous" } 113 #pragma omp declare reduction (bar: S: omp_out.s += omp_in.s) // { dg-error "cannot be overloaded" } 114 #pragma omp declare reduction (bar: long: omp_out += omp_in) // { dg-message "previous" } 115 #pragma omp declare reduction (bar: long int: omp_out += omp_in) // { dg-error "cannot be overloaded" } 116 #pragma omp declare reduction (bar: short unsigned: omp_out += omp_in) 117 #pragma omp declare reduction (bar: short int: omp_out += omp_in) 118 }; 119 } 120 121 namespace N5 122 { 123 template <typename T> 124 int f7()125 f7 () 126 { 127 #pragma omp declare reduction (f7: T: omp_out.s *= omp_in.s) // { dg-message "previous" } 128 #pragma omp declare reduction (f7: T: omp_out.s += omp_in.s) // { dg-error "redeclaration of" } 129 return 0; 130 } 131 int x = f7 <S> (); 132 template <typename T> 133 struct U 134 { 135 #pragma omp declare reduction (bar: T: omp_out.s *= omp_in.s) // { dg-message "previous" } 136 #pragma omp declare reduction (bar: T: omp_out.s += omp_in.s) // { dg-error "cannot be overloaded" } 137 }; 138 U<S> u; 139 } 140 141 namespace N6 142 { 143 template <typename U> 144 int f8()145 f8 () 146 { 147 #pragma omp declare reduction (f8: T: omp_out.t += omp_in.t) 148 #pragma omp declare reduction (f8: U: omp_out.s *= omp_in.s) // { dg-message "previous" } 149 #pragma omp declare reduction (f8: ::S: omp_out.s += omp_in.s) // { dg-error "redeclaration of" } 150 #pragma omp declare reduction (f8: long: omp_out += omp_in) // { dg-message "previous" } 151 #pragma omp declare reduction (f8: long int: omp_out += omp_in) // { dg-error "redeclaration of" } 152 #pragma omp declare reduction (f8: short unsigned: omp_out += omp_in) 153 #pragma omp declare reduction (f8: short int: omp_out += omp_in) 154 return 0; 155 } 156 int x = f8 <S> (); 157 template <typename V> 158 struct U 159 { 160 typedef V V2; 161 #pragma omp declare reduction (bar: T: omp_out.t += omp_in.t) 162 #pragma omp declare reduction (bar: V: omp_out.s *= omp_in.s) // { dg-message "previous" } 163 #pragma omp declare reduction (bar: V2: omp_out.s += omp_in.s) // { dg-error "cannot be overloaded" } 164 #pragma omp declare reduction (bar: long: omp_out += omp_in) // { dg-message "previous" } 165 #pragma omp declare reduction (bar: long int: omp_out += omp_in) // { dg-error "cannot be overloaded" } 166 #pragma omp declare reduction (bar: short unsigned: omp_out += omp_in) 167 #pragma omp declare reduction (bar: short int: omp_out += omp_in) 168 }; 169 U<S> u; 170 } 171 172 namespace N7 173 { 174 #pragma omp declare reduction (+: S: omp_out.s += omp_in.s) initializer (omp_priv) // { dg-error "invalid initializer clause" } 175 #pragma omp declare reduction (+: T: omp_out.t += omp_in.t) initializer (omp_priv ()) // { dg-error "invalid initializer clause" } 176 } 177 178 namespace N8 179 { 180 struct A { int a; A (); ~A (); }; 181 struct B { int b; B (); ~B (); B (int); }; 182 struct C : public A, B { int c; C (); ~C (); }; 183 #pragma omp declare reduction (+:B:omp_out.b += omp_in.b) initializer (omp_priv (4)) 184 void bar (C &); baz()185 void baz () 186 { 187 C a; 188 #pragma omp parallel reduction (+:a) // { dg-error "user defined reduction with constructor initializer for base class" } 189 bar (a); 190 } 191 } 192