Patchwork Fix postincrement/decrement of a bitfield (PR middle-end/55750)

login
register
mail settings
Submitter Jakub Jelinek
Date Dec. 20, 2012, 5:06 p.m.
Message ID <20121220170623.GC2315@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/207686/
State New
Headers show

Comments

Jakub Jelinek - Dec. 20, 2012, 5:06 p.m.
Hi!

As the following testcase shows, the !is_gimple_min_lval code would for bit
fields want to take address of those bitfields and dereference it, which of
course leads to ICEs.

As discussed with Richard on IRC, this code is not needed at all since
PR48814 fix, so there is no need to teach it about bitfields and instead it
can be just removed altogether.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2012-12-20  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/55750
	* gimplify.c (gimplify_self_mod_expr): Don't force lvalue to
	pass is_gimple_min_lval.

	* gcc.c-torture/execute/pr55750.c: New test.


	Jakub
Richard Guenther - Dec. 20, 2012, 5:47 p.m.
Jakub Jelinek <jakub@redhat.com> wrote:

>Hi!
>
>As the following testcase shows, the !is_gimple_min_lval code would for
>bit
>fields want to take address of those bitfields and dereference it,
>which of
>course leads to ICEs.
>
>As discussed with Richard on IRC, this code is not needed at all since
>PR48814 fix, so there is no need to teach it about bitfields and
>instead it
>can be just removed altogether.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

>2012-12-20  Jakub Jelinek  <jakub@redhat.com>
>
>	PR middle-end/55750
>	* gimplify.c (gimplify_self_mod_expr): Don't force lvalue to
>	pass is_gimple_min_lval.
>
>	* gcc.c-torture/execute/pr55750.c: New test.
>
>--- gcc/gimplify.c.jj	2012-12-20 11:38:45.000000000 +0100
>+++ gcc/gimplify.c	2012-12-20 14:45:42.586627882 +0100
>@@ -2391,25 +2391,15 @@ gimplify_self_mod_expr (tree *expr_p, gi
>   rhs = TREE_OPERAND (*expr_p, 1);
> 
> /* For postfix operator, we evaluate the LHS to an rvalue and then use
>-     that as the result value and in the postqueue operation.  We also
>-     make sure to make lvalue a minimal lval, see
>-     gcc.c-torture/execute/20040313-1.c for an example where this
>matters.  */
>+     that as the result value and in the postqueue operation.  */
>   if (postfix)
>     {
>-      if (!is_gimple_min_lval (lvalue))
>-	{
>-	  mark_addressable (lvalue);
>-	  lvalue = build_fold_addr_expr_loc (input_location, lvalue);
>-	  gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue);
>-	  lvalue = build_fold_indirect_ref_loc (input_location, lvalue);
>-	}
>   ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
>       if (ret == GS_ERROR)
> 	return ret;
>-    }
> 
>-  if (postfix)
>-    lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
>+      lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
>+    }
> 
>   /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
>   if (POINTER_TYPE_P (TREE_TYPE (lhs)))
>--- gcc/testsuite/gcc.c-torture/execute/pr55750.c.jj	2012-12-20
>14:24:03.487344949 +0100
>+++ gcc/testsuite/gcc.c-torture/execute/pr55750.c	2012-12-20
>14:25:10.000000000 +0100
>@@ -0,0 +1,29 @@
>+/* PR middle-end/55750 */
>+
>+extern void abort (void);
>+
>+struct S
>+{
>+  int m : 1;
>+  int n : 7;
>+} arr[2];
>+
>+__attribute__((noinline, noclone)) void
>+foo (unsigned i)
>+{
>+  arr[i].n++;
>+}
>+
>+int
>+main ()
>+{
>+  arr[0].m = -1;
>+  arr[0].n = (1 << 6) - 1;
>+  arr[1].m = 0;
>+  arr[1].n = -1;
>+  foo (0);
>+  foo (1);
>+  if (arr[0].m != -1 || arr[0].n != -(1 << 6) || arr[1].m != 0 ||
>arr[1].n != 0)
>+    abort ();
>+  return 0;
>+}
>
>	Jakub

Patch

--- gcc/gimplify.c.jj	2012-12-20 11:38:45.000000000 +0100
+++ gcc/gimplify.c	2012-12-20 14:45:42.586627882 +0100
@@ -2391,25 +2391,15 @@  gimplify_self_mod_expr (tree *expr_p, gi
   rhs = TREE_OPERAND (*expr_p, 1);
 
   /* For postfix operator, we evaluate the LHS to an rvalue and then use
-     that as the result value and in the postqueue operation.  We also
-     make sure to make lvalue a minimal lval, see
-     gcc.c-torture/execute/20040313-1.c for an example where this matters.  */
+     that as the result value and in the postqueue operation.  */
   if (postfix)
     {
-      if (!is_gimple_min_lval (lvalue))
-	{
-	  mark_addressable (lvalue);
-	  lvalue = build_fold_addr_expr_loc (input_location, lvalue);
-	  gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue);
-	  lvalue = build_fold_indirect_ref_loc (input_location, lvalue);
-	}
       ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
       if (ret == GS_ERROR)
 	return ret;
-    }
 
-  if (postfix)
-    lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
+      lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
+    }
 
   /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
   if (POINTER_TYPE_P (TREE_TYPE (lhs)))
--- gcc/testsuite/gcc.c-torture/execute/pr55750.c.jj	2012-12-20 14:24:03.487344949 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr55750.c	2012-12-20 14:25:10.000000000 +0100
@@ -0,0 +1,29 @@ 
+/* PR middle-end/55750 */
+
+extern void abort (void);
+
+struct S
+{
+  int m : 1;
+  int n : 7;
+} arr[2];
+
+__attribute__((noinline, noclone)) void
+foo (unsigned i)
+{
+  arr[i].n++;
+}
+
+int
+main ()
+{
+  arr[0].m = -1;
+  arr[0].n = (1 << 6) - 1;
+  arr[1].m = 0;
+  arr[1].n = -1;
+  foo (0);
+  foo (1);
+  if (arr[0].m != -1 || arr[0].n != -(1 << 6) || arr[1].m != 0 || arr[1].n != 0)
+    abort ();
+  return 0;
+}