re PR middle-end/59138 (possible packed struct miscompile)
PR middle-end/59138 * expr.c (emit_group_store): Don't write past the end of the structure. (store_bit_field): Fix formatting. From-SVN: r205436
This commit is contained in:
parent
43ad66aa4a
commit
ca85aa4ae6
4 changed files with 61 additions and 9 deletions
|
@ -1,3 +1,9 @@
|
|||
2013-11-27 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
PR middle-end/59138
|
||||
* expr.c (emit_group_store): Don't write past the end of the structure.
|
||||
(store_bit_field): Fix formatting.
|
||||
|
||||
2013-11-27 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/59288
|
||||
|
|
26
gcc/expr.c
26
gcc/expr.c
|
@ -2061,12 +2061,14 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
|
|||
HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (src, 0, i), 1));
|
||||
enum machine_mode mode = GET_MODE (tmps[i]);
|
||||
unsigned int bytelen = GET_MODE_SIZE (mode);
|
||||
unsigned int adj_bytelen = bytelen;
|
||||
unsigned int adj_bytelen;
|
||||
rtx dest = dst;
|
||||
|
||||
/* Handle trailing fragments that run over the size of the struct. */
|
||||
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
|
||||
adj_bytelen = ssize - bytepos;
|
||||
else
|
||||
adj_bytelen = bytelen;
|
||||
|
||||
if (GET_CODE (dst) == CONCAT)
|
||||
{
|
||||
|
@ -2107,6 +2109,7 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
|
|||
}
|
||||
}
|
||||
|
||||
/* Handle trailing fragments that run over the size of the struct. */
|
||||
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
|
||||
{
|
||||
/* store_bit_field always takes its value from the lsb.
|
||||
|
@ -2124,16 +2127,22 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
|
|||
tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
|
||||
shift, tmps[i], 0);
|
||||
}
|
||||
bytelen = adj_bytelen;
|
||||
|
||||
/* Make sure not to write past the end of the struct. */
|
||||
store_bit_field (dest,
|
||||
adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
|
||||
bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT,
|
||||
VOIDmode, tmps[i]);
|
||||
}
|
||||
|
||||
/* Optimize the access just a bit. */
|
||||
if (MEM_P (dest)
|
||||
&& (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
|
||||
|| MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
|
||||
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
|
||||
&& bytelen == GET_MODE_SIZE (mode))
|
||||
else if (MEM_P (dest)
|
||||
&& (!SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
|
||||
|| MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
|
||||
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
|
||||
&& bytelen == GET_MODE_SIZE (mode))
|
||||
emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
|
||||
|
||||
else
|
||||
store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
|
||||
0, 0, mode, tmps[i]);
|
||||
|
@ -4776,8 +4785,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
|||
expand_insn (icode, 2, ops);
|
||||
}
|
||||
else
|
||||
store_bit_field (mem, GET_MODE_BITSIZE (mode),
|
||||
0, 0, 0, mode, reg);
|
||||
store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2013-11-27 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc.c-torture/execute/20131127-1.c: New test.
|
||||
|
||||
2013-11-27 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/59288
|
||||
|
|
34
gcc/testsuite/gcc.c-torture/execute/20131127-1.c
Normal file
34
gcc/testsuite/gcc.c-torture/execute/20131127-1.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* PR middle-end/59138 */
|
||||
/* Testcase by John Regehr <regehr@cs.utah.edu> */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct S0 {
|
||||
int f0;
|
||||
int f1;
|
||||
int f2;
|
||||
short f3;
|
||||
};
|
||||
|
||||
short a = 1;
|
||||
|
||||
struct S0 b = { 1 }, c, d, e;
|
||||
|
||||
struct S0 fn1() { return c; }
|
||||
|
||||
void fn2 (void)
|
||||
{
|
||||
b = fn1 ();
|
||||
a = 0;
|
||||
d = e;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
fn2 ();
|
||||
if (a != 0)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue