aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2013-09-20 14:10:14 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2013-09-20 14:10:14 +0000
commit59bb154488e270f67308538c5bba68e478b8ad9c (patch)
tree43f1354bf199e4c44aa97bee28fbf5063ffe50a7
parenta54300190578a207d66e7db8931eabe936261c14 (diff)
downloadgcc-59bb154488e270f67308538c5bba68e478b8ad9c.zip
gcc-59bb154488e270f67308538c5bba68e478b8ad9c.tar.gz
gcc-59bb154488e270f67308538c5bba68e478b8ad9c.tar.bz2
re PR middle-end/57748 (ICE when expanding assignment to unaligned zero-sized array)
2013-09-20 Bernd Edlinger <bernd.edlinger@hotmail.de> 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
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/expr.c48
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57748-1.c49
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57748-2.c43
5 files changed, 104 insertions, 47 deletions
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 <bernd.edlinger@hotmail.de>
+
+ PR middle-end/57748
+ * expr.c (expand_assignment): Remove misalignp code path.
+
2013-09-20 Marek Polacek <polacek@redhat.com>
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<mode> 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<mode> 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 <bernd.edlinger@hotmail.de>
+
+ 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 <polacek@redhat.com>
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 <stdlib.h>
+
+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 <stdlib.h>
+
+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;
+}