[committed] Fix OpenMP reduction with _Complex vars (PR middle-end/58809)

Jakub Jelinek jakub@redhat.com
Thu Jan 23 13:37:00 GMT 2014


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  <jakub@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
-------------- next part --------------
2014-01-23  Jakub Jelinek  <jakub@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" } */
+    ;
+}


More information about the Gcc-patches mailing list