]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c/45784 (gcc OpenMP - error: invalid controlling predicate)
authorJakub Jelinek <jakub@redhat.com>
Fri, 15 Sep 2017 21:33:08 +0000 (23:33 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 15 Sep 2017 21:33:08 +0000 (23:33 +0200)
Backported from mainline
2017-07-27  Jakub Jelinek  <jakub@redhat.com>

PR c/45784
* c-omp.c (c_finish_omp_for): If the condition is wrapped in
rhs of COMPOUND_EXPR(s), skip them and readd their lhs into
new COMPOUND_EXPRs around the rhs of the comparison.

* testsuite/libgomp.c/pr45784.c: New test.
* testsuite/libgomp.c++/pr45784.C: New test.

From-SVN: r252855

gcc/c-family/ChangeLog
gcc/c-family/c-omp.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/pr45784.C [new file with mode: 0644]
libgomp/testsuite/libgomp.c/pr45784.c [new file with mode: 0644]

index d1ce466a5448af63d2d2c9b207fd6bf447608970..5b1a6f0d5ea8f3db1cb6981a14d5267b4b5358fa 100644 (file)
@@ -1,3 +1,13 @@
+2017-09-15  Jakub Jelinek  <jakub@redhat.com>
+
+       Backported from mainline
+       2017-07-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/45784
+       * c-omp.c (c_finish_omp_for): If the condition is wrapped in
+       rhs of COMPOUND_EXPR(s), skip them and readd their lhs into
+       new COMPOUND_EXPRs around the rhs of the comparison.
+
 2017-09-15  Martin Liska  <mliska@suse.cz>
 
        Backport from mainline
index 1691c40f11a661cafb8fbe53a4689be64d13ad60..36ad6a783df362e8887a9c75aed9fab70984a8fa 100644 (file)
@@ -518,6 +518,12 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
        {
          bool cond_ok = false;
 
+         /* E.g. C sizeof (vla) could add COMPOUND_EXPRs with
+            evaluation of the vla VAR_DECL.  We need to readd
+            them to the non-decl operand.  See PR45784.  */
+         while (TREE_CODE (cond) == COMPOUND_EXPR)
+           cond = TREE_OPERAND (cond, 1);
+
          if (EXPR_HAS_LOCATION (cond))
            elocus = EXPR_LOCATION (cond);
 
@@ -592,6 +598,21 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
                  else if (code != CILK_SIMD && code != CILK_FOR)
                    cond_ok = false;
                }
+
+             if (cond_ok && TREE_VEC_ELT (condv, i) != cond)
+               {
+                 tree ce = NULL_TREE, *pce = &ce;
+                 tree type = TREE_TYPE (TREE_OPERAND (cond, 1));
+                 for (tree c = TREE_VEC_ELT (condv, i); c != cond;
+                      c = TREE_OPERAND (c, 1))
+                   {
+                     *pce = build2 (COMPOUND_EXPR, type, TREE_OPERAND (c, 0),
+                                    TREE_OPERAND (cond, 1));
+                     pce = &TREE_OPERAND (*pce, 1);
+                   }
+                 TREE_OPERAND (cond, 1) = ce;
+                 TREE_VEC_ELT (condv, i) = cond;
+               }
            }
 
          if (!cond_ok)
index 7396f673c0a71f73cd52b42fdd9aad2f940bd6e3..6de6c7cd3be2c24eb18ecb904050c741ae19904d 100644 (file)
@@ -1,3 +1,12 @@
+2017-09-15  Jakub Jelinek  <jakub@redhat.com>
+
+       Backported from mainline
+       2017-07-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/45784
+       * testsuite/libgomp.c/pr45784.c: New test.
+       * testsuite/libgomp.c++/pr45784.C: New test.
+
 2017-07-04  Release Manager
 
        * GCC 6.4.0 released.
diff --git a/libgomp/testsuite/libgomp.c++/pr45784.C b/libgomp/testsuite/libgomp.c++/pr45784.C
new file mode 100644 (file)
index 0000000..306246c
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c/45784
+// { dg-do run }
+
+#include "../libgomp.c/pr45784.c"
+
diff --git a/libgomp/testsuite/libgomp.c/pr45784.c b/libgomp/testsuite/libgomp.c/pr45784.c
new file mode 100644 (file)
index 0000000..7861210
--- /dev/null
@@ -0,0 +1,41 @@
+/* PR c/45784 */
+/* { dg-do run } */
+
+void
+foo (int n)
+{
+  char *p, vla[2 * n];
+  int i;
+  #pragma omp parallel for
+  for (p = vla; p < vla + (sizeof (vla) / sizeof (vla[0])); p++)
+    *p = ' ';
+  #pragma omp parallel for
+  for (i = 0; i < 2 * n; i++)
+    if (vla[i] != ' ')
+      __builtin_abort ();
+}
+
+void
+bar (int n)
+{
+  char *p, vla1[n], vla2[n * 2], vla3[n * 3], vla4[n * 4];
+  int i;
+  __builtin_memset (vla4, ' ', n * 4);
+  #pragma omp parallel for
+  for (p = vla4 + sizeof (vla1); p < vla4 + sizeof (vla3) - sizeof (vla2) + sizeof (vla1); p += sizeof (vla4) / sizeof (vla4))
+    p[0] = '!';
+  #pragma omp parallel for
+  for (i = 0; i < n * 4; i++)
+    if (vla4[i] != ((i >= n && i < 2 * n) ? '!' : ' '))
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  volatile int n;
+  n = 128;
+  foo (n);
+  bar (n);
+  return 0;
+}