mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-19 07:10:25 +08:00
re PR middle-end/59134 (infinite loop between store_fixed_bit_field and store_split_bit_field with STRICT_ALIGNMENT)
2013-12-11 Bernd Edlinger <bernd.edlinger@hotmail.de> PR middle-end/59134 * expmed.c (store_bit_field): Use narrow_bit_field_mem and store_fixed_bit_field_1 for -fstrict-volatile-bitfields. (store_fixed_bit_field): Split up. Call store_fixed_bit_field_1 to do the real work. (store_fixed_bit_field_1): New function. (store_split_bit_field): Limit the unit size to the memory mode size, to prevent recursion. testsuite: * gcc.c-torture/compile/pr59134.c: New test. * gnat.dg/misaligned_volatile.adb: New test. From-SVN: r205898
This commit is contained in:
parent
6f4e9cf842
commit
ebb99f967b
@ -1,3 +1,14 @@
|
||||
2013-12-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
PR middle-end/59134
|
||||
* expmed.c (store_bit_field): Use narrow_bit_field_mem and
|
||||
store_fixed_bit_field_1 for -fstrict-volatile-bitfields.
|
||||
(store_fixed_bit_field): Split up. Call store_fixed_bit_field_1
|
||||
to do the real work.
|
||||
(store_fixed_bit_field_1): New function.
|
||||
(store_split_bit_field): Limit the unit size to the memory mode size,
|
||||
to prevent recursion.
|
||||
|
||||
2013-12-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
Sandra Loosemore <sandra@codesourcery.com>
|
||||
|
||||
|
43
gcc/expmed.c
43
gcc/expmed.c
@ -48,6 +48,9 @@ static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT,
|
||||
rtx);
|
||||
static void store_fixed_bit_field_1 (rtx, unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT,
|
||||
rtx);
|
||||
static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT,
|
||||
@ -948,10 +951,16 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
|
||||
emit_move_insn (str_rtx, value);
|
||||
}
|
||||
else
|
||||
/* Explicitly override the C/C++ memory model; ignore the
|
||||
bit range so that we can do the access in the mode mandated
|
||||
by -fstrict-volatile-bitfields instead. */
|
||||
store_fixed_bit_field (str_rtx, bitsize, bitnum, 0, 0, value);
|
||||
{
|
||||
str_rtx = narrow_bit_field_mem (str_rtx, fieldmode, bitsize, bitnum,
|
||||
&bitnum);
|
||||
/* Explicitly override the C/C++ memory model; ignore the
|
||||
bit range so that we can do the access in the mode mandated
|
||||
by -fstrict-volatile-bitfields instead. */
|
||||
store_fixed_bit_field_1 (str_rtx, bitsize, bitnum,
|
||||
value);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -994,9 +1003,6 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
|
||||
rtx value)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
rtx temp;
|
||||
int all_zero = 0;
|
||||
int all_one = 0;
|
||||
|
||||
/* There is a case not handled here:
|
||||
a structure with a known alignment of just a halfword
|
||||
@ -1026,6 +1032,23 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
|
||||
op0 = narrow_bit_field_mem (op0, mode, bitsize, bitnum, &bitnum);
|
||||
}
|
||||
|
||||
store_fixed_bit_field_1 (op0, bitsize, bitnum, value);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Helper function for store_fixed_bit_field, stores
|
||||
the bit field always using the MODE of OP0. */
|
||||
|
||||
static void
|
||||
store_fixed_bit_field_1 (rtx op0, unsigned HOST_WIDE_INT bitsize,
|
||||
unsigned HOST_WIDE_INT bitnum,
|
||||
rtx value)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
rtx temp;
|
||||
int all_zero = 0;
|
||||
int all_one = 0;
|
||||
|
||||
mode = GET_MODE (op0);
|
||||
gcc_assert (SCALAR_INT_MODE_P (mode));
|
||||
|
||||
@ -1134,6 +1157,12 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
|
||||
else
|
||||
unit = MIN (MEM_ALIGN (op0), BITS_PER_WORD);
|
||||
|
||||
/* If OP0 is a memory with a mode, then UNIT must not be larger than
|
||||
OP0's mode as well. Otherwise, store_fixed_bit_field will call us
|
||||
again, and we will mutually recurse forever. */
|
||||
if (MEM_P (op0) && GET_MODE_BITSIZE (GET_MODE (op0)) > 0)
|
||||
unit = MIN (unit, GET_MODE_BITSIZE (GET_MODE (op0)));
|
||||
|
||||
/* If VALUE is a constant other than a CONST_INT, get it into a register in
|
||||
WORD_MODE. If we can do this using gen_lowpart_common, do so. Note
|
||||
that VALUE might be a floating-point constant. */
|
||||
|
@ -1,3 +1,9 @@
|
||||
2013-12-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
PR middle-end/59134
|
||||
* gcc.c-torture/compile/pr59134.c: New test.
|
||||
* gnat.dg/misaligned_volatile.adb: New test.
|
||||
|
||||
2013-12-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
Sandra Loosemore <sandra@codesourcery.com>
|
||||
|
||||
|
16
gcc/testsuite/gcc.c-torture/compile/pr59134.c
Normal file
16
gcc/testsuite/gcc.c-torture/compile/pr59134.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
extern void* malloc(__SIZE_TYPE__) __attribute__((malloc));
|
||||
|
||||
typedef struct {
|
||||
char pad;
|
||||
int arr[0];
|
||||
} __attribute__((packed)) str;
|
||||
|
||||
str *
|
||||
foo (void)
|
||||
{
|
||||
str *s = malloc (sizeof (str) + sizeof (int));
|
||||
s->arr[0] = 0x12345678;
|
||||
return s;
|
||||
}
|
28
gcc/testsuite/gnat.dg/misaligned_volatile.adb
Normal file
28
gcc/testsuite/gnat.dg/misaligned_volatile.adb
Normal file
@ -0,0 +1,28 @@
|
||||
-- { dg-do run }
|
||||
-- { dg-options "-gnatp -fstrict-volatile-bitfields" }
|
||||
|
||||
procedure Misaligned_Volatile is
|
||||
|
||||
type Byte is mod 2**8;
|
||||
|
||||
type Block is record
|
||||
B : Boolean;
|
||||
V : Byte;
|
||||
end record;
|
||||
pragma Volatile (Block);
|
||||
pragma Pack (Block);
|
||||
for Block'Alignment use 1;
|
||||
|
||||
type Pair is array (1 .. 2) of Block;
|
||||
|
||||
P : Pair;
|
||||
begin
|
||||
for K in P'Range loop
|
||||
P(K).V := 237;
|
||||
end loop;
|
||||
for K in P'Range loop
|
||||
if P(K).V /= 237 then
|
||||
raise Program_error;
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
Loading…
x
Reference in New Issue
Block a user