re PR c++/88976 (ICE in fold_convert_loc, at fold-const.c:2552)
authorJakub Jelinek <jakub@redhat.com>
Thu, 24 Jan 2019 19:16:21 +0000 (20:16 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 24 Jan 2019 19:16:21 +0000 (20:16 +0100)
PR c++/88976
* c-typeck.c (c_finish_omp_cancel): Diagnose more than one if
on #pragma omp cancel with different modifiers.

* semantics.c (finish_omp_cancel): Diagnose more than one if
on #pragma omp cancel with different modifiers.  Use
maybe_convert_cond when not in template or build_x_binary_op
otherwise.

* c-c++-common/gomp/cancel-2.c: New test.
* gcc.dg/gomp/cancel-1.c: New test.
* g++.dg/gomp/cancel-1.C: New test.
* g++.dg/gomp/cancel-2.C: New test.
* g++.dg/gomp/cancel-3.C: New test.

From-SVN: r268245

gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/gomp/cancel-2.c [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/cancel-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/cancel-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/cancel-3.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/cancel-1.c [new file with mode: 0644]

index fe83d69de8777cd6fd52284df31be5fddd5d5145..32c77f9360b1c5e19ca9d88b8803541974a49c14 100644 (file)
@@ -1,3 +1,9 @@
+2019-01-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/88976
+       * c-typeck.c (c_finish_omp_cancel): Diagnose more than one if
+       on #pragma omp cancel with different modifiers.
+
 2019-01-18  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR c/51628
index cbd612c4fb936c3b3893260ce92e80d583bae387..48112006f04d37763a378dfd2d4d6b5c66d60b44 100644 (file)
@@ -12766,6 +12766,18 @@ c_finish_omp_cancel (location_t loc, tree clauses)
          && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST)
        error_at (OMP_CLAUSE_LOCATION (ifc),
                  "expected %<cancel%> %<if%> clause modifier");
+      else
+       {
+         tree ifc2 = omp_find_clause (OMP_CLAUSE_CHAIN (ifc), OMP_CLAUSE_IF);
+         if (ifc2 != NULL_TREE)
+           {
+             gcc_assert (OMP_CLAUSE_IF_MODIFIER (ifc) == VOID_CST
+                         && OMP_CLAUSE_IF_MODIFIER (ifc2) != ERROR_MARK
+                         && OMP_CLAUSE_IF_MODIFIER (ifc2) != VOID_CST);
+             error_at (OMP_CLAUSE_LOCATION (ifc2),
+                       "expected %<cancel%> %<if%> clause modifier");
+           }
+       }
 
       tree type = TREE_TYPE (OMP_CLAUSE_IF_EXPR (ifc));
       ifc = fold_build2_loc (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
index 58acbf0a24148cbfc73cc4035b04ab1a3e8a8256..99d43c9d7a4e942e57ebe40cb9ac6dddd0be313f 100644 (file)
@@ -1,3 +1,11 @@
+2019-01-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/88976
+       * semantics.c (finish_omp_cancel): Diagnose more than one if
+       on #pragma omp cancel with different modifiers.  Use
+       maybe_convert_cond when not in template or build_x_binary_op
+       otherwise.
+
 2019-01-23  Marek Polacek  <polacek@redhat.com>
 
        PR c++/88757 - qualified name treated wrongly as type.
index e654750d249d7139394be767278b0e9f5ac2bf49..72191395b47bd43d9e5b9c051e3446bcecf07c93 100644 (file)
@@ -9055,11 +9055,26 @@ finish_omp_cancel (tree clauses)
          && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST)
        error_at (OMP_CLAUSE_LOCATION (ifc),
                  "expected %<cancel%> %<if%> clause modifier");
+      else
+       {
+         tree ifc2 = omp_find_clause (OMP_CLAUSE_CHAIN (ifc), OMP_CLAUSE_IF);
+         if (ifc2 != NULL_TREE)
+           {
+             gcc_assert (OMP_CLAUSE_IF_MODIFIER (ifc) == VOID_CST
+                         && OMP_CLAUSE_IF_MODIFIER (ifc2) != ERROR_MARK
+                         && OMP_CLAUSE_IF_MODIFIER (ifc2) != VOID_CST);
+             error_at (OMP_CLAUSE_LOCATION (ifc2),
+                       "expected %<cancel%> %<if%> clause modifier");
+           }
+       }
 
-      tree type = TREE_TYPE (OMP_CLAUSE_IF_EXPR (ifc));
-      ifc = fold_build2_loc (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
-                            boolean_type_node, OMP_CLAUSE_IF_EXPR (ifc),
-                            build_zero_cst (type));
+      if (!processing_template_decl)
+       ifc = maybe_convert_cond (OMP_CLAUSE_IF_EXPR (ifc));
+      else
+       ifc = build_x_binary_op (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
+                                OMP_CLAUSE_IF_EXPR (ifc), ERROR_MARK,
+                                integer_zero_node, ERROR_MARK,
+                                NULL, tf_warning_or_error);
     }
   else
     ifc = boolean_true_node;
index 75467a3f84fa1cd7e3db2730440243790807fcaa..809c952e30ac984bc6d53dc8400abbed8df97cf3 100644 (file)
@@ -1,3 +1,12 @@
+2019-01-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/88976
+       * c-c++-common/gomp/cancel-2.c: New test.
+       * gcc.dg/gomp/cancel-1.c: New test.
+       * g++.dg/gomp/cancel-1.C: New test.
+       * g++.dg/gomp/cancel-2.C: New test.
+       * g++.dg/gomp/cancel-3.C: New test.
+
 2019-01-24  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/89027
diff --git a/gcc/testsuite/c-c++-common/gomp/cancel-2.c b/gcc/testsuite/c-c++-common/gomp/cancel-2.c
new file mode 100644 (file)
index 0000000..bd016c2
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  #pragma omp parallel
+  {
+    #pragma omp cancel parallel if (1) if (1)                  /* { dg-error "too many 'if' clauses without modifier" } */
+    #pragma omp cancel parallel if (cancel: 1) if (cancel: 1)  /* { dg-error "too many 'if' clauses with 'cancel' modifier" } */
+    #pragma omp cancel parallel if (cancel: 1) if (1)          /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+    #pragma omp cancel parallel if (cancel: 1) if (parallel: 1)        /* { dg-error "expected 'cancel' 'if' clause modifier" } */
+    #pragma omp cancel parallel if (1) if (cancel: 1)          /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+    #pragma omp cancel parallel if (parallel: 1) if (cancel: 1)        /* { dg-error "expected 'cancel' 'if' clause modifier" } */
+  }
+}
diff --git a/gcc/testsuite/g++.dg/gomp/cancel-1.C b/gcc/testsuite/g++.dg/gomp/cancel-1.C
new file mode 100644 (file)
index 0000000..a6b1167
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/88976
+// { dg-do compile }
+
+template <class T> void
+foo (T x)
+{
+#pragma omp parallel
+  {
+  #pragma omp cancel parallel if (x)
+  }
+#pragma omp parallel
+  {
+  #pragma omp cancel parallel if (1 == 1)
+  }
+}
+
+void
+bar (int x, double y, long long z)
+{
+  foo (0);
+  foo (1LL);
+  foo (1.25);
+  foo (x);
+  foo (y);
+  foo (z);
+}
diff --git a/gcc/testsuite/g++.dg/gomp/cancel-2.C b/gcc/testsuite/g++.dg/gomp/cancel-2.C
new file mode 100644 (file)
index 0000000..c9269e7
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/88976
+// { dg-do compile }
+
+template <class T> void
+foo (T x)
+{
+#pragma omp parallel
+  {
+  #pragma omp cancel parallel if (x)   // { dg-error "no match for" }
+  }
+}
+
+struct S {};
+
+void
+bar ()
+{
+  S s;
+  foo (s);
+}
diff --git a/gcc/testsuite/g++.dg/gomp/cancel-3.C b/gcc/testsuite/g++.dg/gomp/cancel-3.C
new file mode 100644 (file)
index 0000000..87e757b
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-do compile }
+
+struct S { int s; } s;
+
+void
+foo (void)
+{
+  #pragma omp parallel
+  {
+    #pragma omp cancel parallel if (s) // { dg-error "could not convert 's' from 'S' to 'bool'" }
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/cancel-1.c b/gcc/testsuite/gcc.dg/gomp/cancel-1.c
new file mode 100644 (file)
index 0000000..c283290
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+struct S { int s; } s;
+
+void
+foo (void)
+{
+  #pragma omp parallel
+  {
+    #pragma omp cancel parallel if (s) /* { dg-error "used struct type value where scalar is required" } */
+  }
+}