[backport gcc-4.8/trunk r194647, fixes PR55750 regression from PR35634 backport, fix depends on PR48814 backport ] Date: Thu, 20 Dec 2012 18:06:23 +0100 From: Jakub Jelinek Subject: [PATCH] Fix postincrement/decrement of a bitfield (PR middle-end/55750) List-Archive: 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? gcc/ 2012-12-20 Jakub Jelinek PR middle-end/55750 * gimplify.c (gimplify_self_mod_expr): Don't force lvalue to pass is_gimple_min_lval. gcc/testsuite/ 2012-12-20 Jakub Jelinek PR middle-end/55750 * gcc.c-torture/execute/pr55750.c: New test. --- gcc-4.7.2/gcc/gimplify.c.~1~ 2012-12-22 17:37:47.000000000 +0100 +++ gcc-4.7.2/gcc/gimplify.c 2012-12-22 17:38:06.000000000 +0100 @@ -2248,25 +2248,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-4.7.2/gcc/testsuite/gcc.c-torture/execute/pr55750.c.~1~ 2012-12-22 17:38:06.000000000 +0100 +++ gcc-4.7.2/gcc/testsuite/gcc.c-torture/execute/pr55750.c 2012-12-22 17:38:06.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; +}