From 59bb154488e270f67308538c5bba68e478b8ad9c Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Fri, 20 Sep 2013 14:10:14 +0000 Subject: [PATCH] re PR middle-end/57748 (ICE when expanding assignment to unaligned zero-sized array) 2013-09-20 Bernd Edlinger PR middle-end/57748 * expr.c (expand_assignment): Remove misalignp code path. testsuite/ PR middle-end/57748 * gcc.dg/torture/pr57748-1.c: New test. * gcc.dg/torture/pr57748-2.c: New test. From-SVN: r202778 --- gcc/ChangeLog | 5 ++++ gcc/expr.c | 48 +------------------------------ gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gcc.dg/torture/pr57748-1.c | 49 ++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr57748-2.c | 43 ++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 47 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr57748-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr57748-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e50e73..7c2b467 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2013-09-20 Bernd Edlinger + + PR middle-end/57748 + * expr.c (expand_assignment): Remove misalignp code path. + 2013-09-20 Marek Polacek PR sanitizer/58413 diff --git a/gcc/expr.c b/gcc/expr.c index 39fa71e..073c335 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4709,8 +4709,6 @@ expand_assignment (tree to, tree from, bool nontemporal) int unsignedp; int volatilep = 0; tree tem; - bool misalignp; - rtx mem = NULL_RTX; push_temp_slots (); tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1, @@ -4720,40 +4718,7 @@ expand_assignment (tree to, tree from, bool nontemporal) && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1))) get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset); - /* If we are going to use store_bit_field and extract_bit_field, - make sure to_rtx will be safe for multiple use. */ - mode = TYPE_MODE (TREE_TYPE (tem)); - if (TREE_CODE (tem) == MEM_REF - && mode != BLKmode - && ((align = get_object_alignment (tem)) - < GET_MODE_ALIGNMENT (mode)) - && ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing)) - { - struct expand_operand ops[2]; - - misalignp = true; - to_rtx = gen_reg_rtx (mode); - mem = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE); - - /* If the misaligned store doesn't overwrite all bits, perform - rmw cycle on MEM. */ - if (bitsize != GET_MODE_BITSIZE (mode)) - { - create_input_operand (&ops[0], to_rtx, mode); - create_fixed_operand (&ops[1], mem); - /* The movmisalign pattern cannot fail, else the assignment - would silently be omitted. */ - expand_insn (icode, 2, ops); - - mem = copy_rtx (mem); - } - } - else - { - misalignp = false; - to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE); - } + to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE); /* If the bitfield is volatile, we want to access it in the field's mode, not the computed mode. @@ -4892,17 +4857,6 @@ expand_assignment (tree to, tree from, bool nontemporal) get_alias_set (to), nontemporal); } - if (misalignp) - { - struct expand_operand ops[2]; - - create_fixed_operand (&ops[0], mem); - create_input_operand (&ops[1], to_rtx, mode); - /* The movmisalign pattern cannot fail, else the assignment - would silently be omitted. */ - expand_insn (icode, 2, ops); - } - if (result) preserve_temp_slots (result); pop_temp_slots (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f341632..0d6438b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-09-20 Bernd Edlinger + + PR middle-end/57748 + * gcc.dg/torture/pr57748-1.c: New test. + * gcc.dg/torture/pr57748-2.c: New test. + 2013-09-20 Marek Polacek PR sanitizer/58413 diff --git a/gcc/testsuite/gcc.dg/torture/pr57748-1.c b/gcc/testsuite/gcc.dg/torture/pr57748-1.c new file mode 100644 index 0000000..dc0fcdc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57748-1.c @@ -0,0 +1,49 @@ +/* PR middle-end/57748 */ +/* { dg-do run } */ +/* ICE in expand_assignment: + misalignp == true, !MEM_P (to_rtx), offset != 0, + => gcc_assert (TREE_CODE (offset) == INTEGER_CST) */ + +#include + +extern void abort (void); + +typedef long long V + __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); + +typedef struct S { V a; V b[0]; } P __attribute__((aligned (1))); + +struct __attribute__((packed)) T { char c; P s; }; + +void __attribute__((noinline, noclone)) +check (struct T *t) +{ + if (t->s.b[0][0] != 3 || t->s.b[0][1] != 4) + abort (); +} + +int __attribute__((noinline, noclone)) +get_i (void) +{ + return 0; +} + +void __attribute__((noinline, noclone)) +foo (P *p) +{ + V a = { 3, 4 }; + int i = get_i (); + p->b[i] = a; +} + +int +main () +{ + struct T *t = (struct T *) calloc (128, 1); + + foo (&t->s); + check (t); + + free (t); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr57748-2.c b/gcc/testsuite/gcc.dg/torture/pr57748-2.c new file mode 100644 index 0000000..4e3b4b8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57748-2.c @@ -0,0 +1,43 @@ +/* PR middle-end/57748 */ +/* { dg-do run } */ +/* wrong code in expand_assignment: + misalignp == true, !MEM_P (to_rtx), + offset == 0, bitpos >= GET_MODE_PRECISION, + => result = NULL. */ + +#include + +extern void abort (void); + +typedef long long V + __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); + +typedef struct S { V a; V b[0]; } P __attribute__((aligned (1))); + +struct __attribute__((packed)) T { char c; P s; }; + +void __attribute__((noinline, noclone)) +check (struct T *t) +{ + if (t->s.b[0][0] != 3 || t->s.b[0][1] != 4) + abort (); +} + +void __attribute__((noinline, noclone)) +foo (P *p) +{ + V a = { 3, 4 }; + p->b[0] = a; +} + +int +main () +{ + struct T *t = (struct T *) calloc (128, 1); + + foo (&t->s); + check (t); + + free (t); + return 0; +} -- 2.7.4