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
This commit is contained in:
parent
a543001905
commit
59bb154488
|
@ -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
|
||||
|
|
48
gcc/expr.c
48
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 ();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue