Hi!

&/|/^ are all rejected for _Complex vars, both floating and integral,
thus OpenMP &/|/^/min/max reductions should be rejected for those vars
similarly.  In OpenMP 4.1 hopefully they'll be allowed for user defined
reductions at least, but they aren't right now.

Below is trunk patch I've committed after testing on x86_64-linux,
attached 4.8 version of the patch.

2014-01-23  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/58809
        * c-typeck.c (c_finish_omp_clause): Reject MIN_EXPR, MAX_EXPR,
        BIT_AND_EXPR, BIT_IOR_EXPR and BIT_XOR_EXPR on COMPLEX_TYPEs.

        * semantics.c (finish_omp_reduction_clause): Reject
        BIT_AND_EXPR, BIT_IOR_EXPR and BIT_XOR_EXPR on COMPLEX_TYPEs.

        * c-c++-common/gomp/pr58809.c: New test.

--- gcc/c/c-typeck.c.jj 2014-01-23 10:53:02.000000000 +0100
+++ gcc/c/c-typeck.c    2014-01-23 13:13:11.268227493 +0100
@@ -11713,7 +11713,8 @@ c_finish_omp_clauses (tree clauses)
          need_implicitly_determined = true;
          t = OMP_CLAUSE_DECL (c);
          if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE
-             && FLOAT_TYPE_P (TREE_TYPE (t)))
+             && (FLOAT_TYPE_P (TREE_TYPE (t))
+                 || TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE))
            {
              enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c);
              const char *r_name = NULL;
@@ -11723,8 +11724,14 @@ c_finish_omp_clauses (tree clauses)
                case PLUS_EXPR:
                case MULT_EXPR:
                case MINUS_EXPR:
+                 break;
                case MIN_EXPR:
+                 if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
+                   r_name = "min";
+                 break;
                case MAX_EXPR:
+                 if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
+                   r_name = "max";
                  break;
                case BIT_AND_EXPR:
                  r_name = "&";
@@ -11736,10 +11743,12 @@ c_finish_omp_clauses (tree clauses)
                  r_name = "|";
                  break;
                case TRUTH_ANDIF_EXPR:
-                 r_name = "&&";
+                 if (FLOAT_TYPE_P (TREE_TYPE (t)))
+                   r_name = "&&";
                  break;
                case TRUTH_ORIF_EXPR:
-                 r_name = "||";
+                 if (FLOAT_TYPE_P (TREE_TYPE (t)))
+                   r_name = "||";
                  break;
                default:
                  gcc_unreachable ();
--- gcc/cp/semantics.c.jj       2014-01-23 11:40:53.000000000 +0100
+++ gcc/cp/semantics.c  2014-01-23 13:04:20.428976929 +0100
@@ -4971,6 +4971,10 @@ finish_omp_reduction_clause (tree c, boo
       case BIT_AND_EXPR:
       case BIT_IOR_EXPR:
       case BIT_XOR_EXPR:
+       if (FLOAT_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)
+         break;
+       predefined = true;
+       break;
       case TRUTH_ANDIF_EXPR:
       case TRUTH_ORIF_EXPR:
        if (FLOAT_TYPE_P (type))
--- gcc/testsuite/c-c++-common/gomp/pr58809.c.jj        2014-01-23 
13:16:37.401160870 +0100
+++ gcc/testsuite/c-c++-common/gomp/pr58809.c   2014-01-23 13:14:32.000000000 
+0100
@@ -0,0 +1,31 @@
+/* PR middle-end/58809 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+_Complex int j;
+_Complex double d;
+
+void
+foo (void)
+{
+  #pragma omp parallel reduction (&:j) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (|:j) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (^:j) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (min:j) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (max:j) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (&:d) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (|:d) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (^:d) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (min:d) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+  #pragma omp parallel reduction (max:d) /* { dg-error "has invalid type 
for|user defined reduction not found for" } */
+    ;
+}

        Jakub
2014-01-23  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/58809
        * c-typeck.c (c_finish_omp_clause): Reject MIN_EXPR, MAX_EXPR,
        BIT_AND_EXPR, BIT_IOR_EXPR and BIT_XOR_EXPR on COMPLEX_TYPEs.

        * semantics.c (finish_omp_clauses): Reject MIN_EXPR, MAX_EXPR,
        BIT_AND_EXPR, BIT_IOR_EXPR and BIT_XOR_EXPR on COMPLEX_TYPEs.

        * c-c++-common/gomp/pr58809.c: New test.

--- gcc/c/c-typeck.c.jj 2014-01-23 14:00:06.860848998 +0100
+++ gcc/c/c-typeck.c    2014-01-23 14:16:30.363885093 +0100
@@ -10623,7 +10623,8 @@ c_finish_omp_clauses (tree clauses)
                        "%qE has invalid type for %<reduction%>", t);
              remove = true;
            }
-         else if (FLOAT_TYPE_P (TREE_TYPE (t)))
+         else if (FLOAT_TYPE_P (TREE_TYPE (t))
+                  || TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
            {
              enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c);
              const char *r_name = NULL;
@@ -10633,8 +10634,14 @@ c_finish_omp_clauses (tree clauses)
                case PLUS_EXPR:
                case MULT_EXPR:
                case MINUS_EXPR:
+                 break;
                case MIN_EXPR:
+                 if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
+                   r_name = "min";
+                 break;
                case MAX_EXPR:
+                 if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
+                   r_name = "max";
                  break;
                case BIT_AND_EXPR:
                  r_name = "&";
@@ -10646,10 +10653,12 @@ c_finish_omp_clauses (tree clauses)
                  r_name = "|";
                  break;
                case TRUTH_ANDIF_EXPR:
-                 r_name = "&&";
+                 if (FLOAT_TYPE_P (TREE_TYPE (t)))
+                   r_name = "&&";
                  break;
                case TRUTH_ORIF_EXPR:
-                 r_name = "||";
+                 if (FLOAT_TYPE_P (TREE_TYPE (t)))
+                   r_name = "||";
                  break;
                default:
                  gcc_unreachable ();
--- gcc/cp/semantics.c.jj       2014-01-23 14:09:49.580939433 +0100
+++ gcc/cp/semantics.c  2014-01-23 14:21:21.121347516 +0100
@@ -4291,7 +4291,8 @@ finish_omp_clauses (tree clauses)
              error ("%qE has invalid type for %<reduction%>", t);
              remove = true;
            }
-         else if (FLOAT_TYPE_P (TREE_TYPE (t)))
+         else if (FLOAT_TYPE_P (TREE_TYPE (t))
+                  || TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
            {
              enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c);
              switch (r_code)
@@ -4299,10 +4300,26 @@ finish_omp_clauses (tree clauses)
                case PLUS_EXPR:
                case MULT_EXPR:
                case MINUS_EXPR:
+                 break;
                case MIN_EXPR:
                case MAX_EXPR:
+                 if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
+                   r_code = ERROR_MARK;
                  break;
+               case BIT_AND_EXPR:
+               case BIT_XOR_EXPR:
+               case BIT_IOR_EXPR:
                default:
+                 r_code = ERROR_MARK;
+                 break;
+               case TRUTH_ANDIF_EXPR:
+               case TRUTH_ORIF_EXPR:
+                 if (FLOAT_TYPE_P (TREE_TYPE (t)))
+                   r_code = ERROR_MARK;
+                 break;
+               }
+             if (r_code == ERROR_MARK)
+               {
                  error ("%qE has invalid type for %<reduction(%s)%>",
                         t, operator_name_info[r_code].name);
                  remove = true;
--- gcc/testsuite/c-c++-common/gomp/pr58809.c.jj        2014-01-23 
14:09:49.580939433 +0100
+++ gcc/testsuite/c-c++-common/gomp/pr58809.c   2014-01-23 14:21:43.292229751 
+0100
@@ -0,0 +1,31 @@
+/* PR middle-end/58809 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+_Complex int j;
+_Complex double d;
+
+void
+foo (void)
+{
+  #pragma omp parallel reduction (&:j) /* { dg-error "has invalid type for" } 
*/
+    ;
+  #pragma omp parallel reduction (|:j) /* { dg-error "has invalid type for" } 
*/
+    ;
+  #pragma omp parallel reduction (^:j) /* { dg-error "has invalid type for" } 
*/
+    ;
+  #pragma omp parallel reduction (min:j) /* { dg-error "has invalid type for" 
} */
+    ;
+  #pragma omp parallel reduction (max:j) /* { dg-error "has invalid type for" 
} */
+    ;
+  #pragma omp parallel reduction (&:d) /* { dg-error "has invalid type for" } 
*/
+    ;
+  #pragma omp parallel reduction (|:d) /* { dg-error "has invalid type for" } 
*/
+    ;
+  #pragma omp parallel reduction (^:d) /* { dg-error "has invalid type for" } 
*/
+    ;
+  #pragma omp parallel reduction (min:d) /* { dg-error "has invalid type for" 
} */
+    ;
+  #pragma omp parallel reduction (max:d) /* { dg-error "has invalid type for" 
} */
+    ;
+}

Reply via email to