re PR middle-end/88968 (Stack overflow in gimplify_expr)
authorJakub Jelinek <jakub@redhat.com>
Tue, 22 Jan 2019 22:28:42 +0000 (23:28 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 22 Jan 2019 22:28:42 +0000 (23:28 +0100)
PR middle-end/88968
* gimplify.c (gimplify_omp_atomic): Handle bitfield atomics with
non-integral DECL_BIT_FIELD_REPRESENTATIVEs.

* c-omp.c (c_finish_omp_atomic): For bitfield atomics, update type
variable after using BIT_FIELD_REF.

* c-c++-common/gomp/atomic-23.c: New test.

From-SVN: r268165

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-omp.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/gomp/atomic-23.c [new file with mode: 0644]

index 548ccdaf11d67ed6169fd5742a508d6498ec7c39..86ebc0f44dde5ec3dc2f9f1be25ff266bfa6a59c 100644 (file)
@@ -1,5 +1,9 @@
 2019-01-22  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/88968
+       * gimplify.c (gimplify_omp_atomic): Handle bitfield atomics with
+       non-integral DECL_BIT_FIELD_REPRESENTATIVEs.
+
        PR target/87064
        * config/rs6000/vsx.md (*vsx_reduc_<VEC_reduc_name>_v2df_scalar):
        Disable for little endian.
index 4aaf8197e7e7bbe3edaeace20c58ef54b4982905..86efe275366673b2db56ca365e678ea0933cb396 100644 (file)
@@ -1,3 +1,9 @@
+2019-01-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/88968
+       * c-omp.c (c_finish_omp_atomic): For bitfield atomics, update type
+       variable after using BIT_FIELD_REF.
+
 2019-01-18  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR c/51628
index 11aeeb008bc035e8ce497c173a8d46768ed2eb83..16e71981887193bb5b19df6387cc776cbe4571da 100644 (file)
@@ -378,8 +378,11 @@ c_finish_omp_atomic (location_t loc, enum tree_code code,
            }
        }
       if (blhs)
-       x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
-                       bitsize_int (bitsize), bitsize_int (bitpos));
+       {
+         x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
+                         bitsize_int (bitsize), bitsize_int (bitpos));
+         type = TREE_TYPE (blhs);
+       }
       x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
                             loc, x, NULL_TREE);
       if (rhs1 && rhs1 != orig_lhs)
index 5677ddd9e84c8847874233f44e8f0867e3acfc2f..59166783eddffeef9c8fb66737c4e748d5571f67 100644 (file)
@@ -11969,9 +11969,36 @@ gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
   loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
                                           OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   gimplify_seq_add_stmt (pre_p, loadstmt);
-  if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
-      != GS_ALL_DONE)
-    return GS_ERROR;
+  if (rhs)
+    {
+      /* BIT_INSERT_EXPR is not valid for non-integral bitfield
+        representatives.  Use BIT_FIELD_REF on the lhs instead.  */
+      if (TREE_CODE (rhs) == BIT_INSERT_EXPR
+         && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
+       {
+         tree bitpos = TREE_OPERAND (rhs, 2);
+         tree op1 = TREE_OPERAND (rhs, 1);
+         tree bitsize;
+         tree tmp_store = tmp_load;
+         if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
+           tmp_store = get_initialized_tmp_var (tmp_load, pre_p, NULL);
+         if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
+           bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
+         else
+           bitsize = TYPE_SIZE (TREE_TYPE (op1));
+         gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
+         tree t = build2_loc (EXPR_LOCATION (rhs),
+                              MODIFY_EXPR, void_type_node,
+                              build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
+                                          TREE_TYPE (op1), tmp_store, bitsize,
+                                          bitpos), op1);
+         gimplify_and_add (t, pre_p);
+         rhs = tmp_store;
+       }
+      if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
+         != GS_ALL_DONE)
+       return GS_ERROR;
+    }
 
   if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
     rhs = tmp_load;
index 66b692e7109453409eb9728c515ba2428e116f91..997b48ef0147d342e738833e8a497becc395f3c3 100644 (file)
@@ -1,3 +1,8 @@
+2019-01-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/88968
+       * c-c++-common/gomp/atomic-23.c: New test.
+
 2019-01-22  Harald Anlauf  <anlauf@gmx.de>
 
        PR fortran/88579
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-23.c b/gcc/testsuite/c-c++-common/gomp/atomic-23.c
new file mode 100644 (file)
index 0000000..969cbf9
--- /dev/null
@@ -0,0 +1,47 @@
+/* PR middle-end/88968 */
+/* { dg-do compile } */
+
+struct __attribute__((packed)) S {
+  unsigned int a : 16;
+  unsigned int b : 1;
+} s;
+
+void
+f1 (void)
+{
+#pragma omp atomic
+  ++s.a;
+}
+
+int
+f2 (void)
+{
+  int r;
+#pragma omp atomic capture
+  {
+    r = s.a;
+    s.a = 0;
+  }
+  return r;
+}
+
+int
+f3 (void)
+{
+  int r;
+#pragma omp atomic capture
+  {
+    r = s.a;
+    s.a = s.a + 32;
+  }
+  return r;
+}
+
+int
+f4 (void)
+{
+  int r;
+#pragma omp atomic capture
+  r = s.a = s.a + 32;
+  return r;
+}