1 // { dg-do compile } 2 // { dg-options "-fopenmp" } 3 4 namespace N1 5 { 6 #pragma omp declare reduction (| : long int : omp_out |= omp_in) // { dg-error "predeclared arithmetic type" } 7 #pragma omp declare reduction (+ : char : omp_out += omp_in) // { dg-error "predeclared arithmetic type" } 8 typedef short T; 9 #pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "predeclared arithmetic type" } 10 #pragma omp declare reduction (* : _Complex double : omp_out *= omp_in)// { dg-error "predeclared arithmetic type" } 11 } 12 namespace N2 13 { 14 template <typename T1, typename T2, typename T3, typename T4> 15 struct S 16 { 17 #pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "predeclared arithmetic type" } 18 #pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "predeclared arithmetic type" } 19 typedef T3 T; 20 #pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "predeclared arithmetic type" } 21 #pragma omp declare reduction (* : T4 : omp_out *= omp_in) // { dg-error "predeclared arithmetic type" } 22 }; 23 S<long int, char, short, _Complex double> s; 24 template <typename T1, typename T2, typename T3, typename T4> foo()25 int foo () 26 { 27 #pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "predeclared arithmetic type" } 28 #pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "predeclared arithmetic type" } 29 typedef T3 T; 30 #pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "predeclared arithmetic type" } 31 #pragma omp declare reduction (* : T4 : omp_out *= omp_in) // { dg-error "predeclared arithmetic type" } 32 return 0; 33 } 34 int x = foo <long int, char, short, _Complex double> (); 35 } 36 namespace N3 37 { 38 void bar (); 39 #pragma omp declare reduction (| : __typeof (bar) : omp_out |= omp_in)// { dg-error "function or array type" } 40 #pragma omp declare reduction (+ : char () : omp_out += omp_in) // { dg-error "function or array type" } 41 typedef short T; 42 #pragma omp declare reduction (min : T[2] : omp_out += omp_in) // { dg-error "function or array type" } 43 #pragma omp declare reduction (baz : char & : omp_out *= omp_in) // { dg-error "reference type" } 44 } 45 namespace N4 46 { 47 void bar (); 48 template <typename T1, typename T2, typename T3, typename T4> 49 struct S 50 { 51 #pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "function or array type" } 52 #pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "function or array type" } 53 typedef T3 T; 54 #pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "function or array type" } 55 #pragma omp declare reduction (baz : T4 : omp_out *= omp_in) // { dg-error "function or array type" } 56 }; 57 S<__typeof (bar), char (), short [3], char []> s; 58 template <typename T1, typename T2, typename T3, typename T4> foo()59 int foo () 60 { 61 #pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "function or array type" } 62 #pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "function or array type" } 63 typedef T3 T; 64 #pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "function or array type" } 65 #pragma omp declare reduction (baz : T4 : omp_out *= omp_in) // { dg-error "function or array type" } 66 return 0; 67 } 68 int x = foo <__typeof (bar), char (), short[], char [2]> (); 69 } 70 namespace N5 71 { 72 template <typename T> 73 struct S 74 { 75 #pragma omp declare reduction (baz : T : omp_out *= omp_in) // { dg-error "reference type" } 76 }; 77 S<char &> s; 78 template <typename T> foo()79 int foo () 80 { 81 #pragma omp declare reduction (baz : T : omp_out *= omp_in) // { dg-error "reference type" } 82 return 0; 83 } 84 int x = foo <char &> (); 85 } 86 namespace N6 87 { AA88 struct A { int a; A () : a (0) {} }; 89 #pragma omp declare reduction (| : const A : omp_out.a |= omp_in.a) // { dg-error "'const', 'volatile' or '__restrict'" } 90 #pragma omp declare reduction (+ : __const A : omp_out.a += omp_in.a) // { dg-error "'const', 'volatile' or '__restrict'" } 91 typedef volatile A T; 92 #pragma omp declare reduction (min : T : omp_out.a += omp_in.a) // { dg-error "'const', 'volatile' or '__restrict'" } 93 #pragma omp declare reduction (* : A *__restrict : omp_out->a *= omp_in->a)// { dg-error "'const', 'volatile' or '__restrict'" } 94 } 95 namespace N7 96 { AA97 struct A { int a; A () : a (0) {} }; 98 template <typename T1, typename T2, typename T3, typename T4> 99 struct S 100 { 101 #pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "'const', 'volatile' or '__restrict'" } 102 #pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "'const', 'volatile' or '__restrict'" } 103 typedef T3 T; 104 #pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "'const', 'volatile' or '__restrict'" } 105 #pragma omp declare reduction (* : T4 : omp_out *= omp_in) // { dg-error "'const', 'volatile' or '__restrict'" } 106 }; 107 S<const A, __const A, volatile A, A *__restrict> s; 108 template <typename T1, typename T2, typename T3, typename T4> foo()109 int foo () 110 { 111 #pragma omp declare reduction (| : T1 : omp_out |= omp_in) // { dg-error "'const', 'volatile' or '__restrict'" } 112 #pragma omp declare reduction (+ : T2 : omp_out += omp_in) // { dg-error "'const', 'volatile' or '__restrict'" } 113 typedef T3 T; 114 #pragma omp declare reduction (min : T : omp_out += omp_in) // { dg-error "'const', 'volatile' or '__restrict'" } 115 #pragma omp declare reduction (* : T4 : omp_out *= omp_in) // { dg-error "'const', 'volatile' or '__restrict'" } 116 return 0; 117 } 118 int x = foo <const A, __const A, volatile A, A *__restrict> (); 119 } 120