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>
|
2013-12-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
Sandra Loosemore <sandra@codesourcery.com>
|
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,
|
||||||
unsigned HOST_WIDE_INT,
|
unsigned HOST_WIDE_INT,
|
||||||
rtx);
|
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,
|
static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT,
|
||||||
unsigned HOST_WIDE_INT,
|
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);
|
emit_move_insn (str_rtx, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Explicitly override the C/C++ memory model; ignore the
|
{
|
||||||
bit range so that we can do the access in the mode mandated
|
str_rtx = narrow_bit_field_mem (str_rtx, fieldmode, bitsize, bitnum,
|
||||||
by -fstrict-volatile-bitfields instead. */
|
&bitnum);
|
||||||
store_fixed_bit_field (str_rtx, bitsize, bitnum, 0, 0, value);
|
/* 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -994,9 +1003,6 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
|
||||||
rtx value)
|
rtx value)
|
||||||
{
|
{
|
||||||
enum machine_mode mode;
|
enum machine_mode mode;
|
||||||
rtx temp;
|
|
||||||
int all_zero = 0;
|
|
||||||
int all_one = 0;
|
|
||||||
|
|
||||||
/* There is a case not handled here:
|
/* There is a case not handled here:
|
||||||
a structure with a known alignment of just a halfword
|
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);
|
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);
|
mode = GET_MODE (op0);
|
||||||
gcc_assert (SCALAR_INT_MODE_P (mode));
|
gcc_assert (SCALAR_INT_MODE_P (mode));
|
||||||
|
|
||||||
|
@ -1134,6 +1157,12 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
|
||||||
else
|
else
|
||||||
unit = MIN (MEM_ALIGN (op0), BITS_PER_WORD);
|
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
|
/* 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
|
WORD_MODE. If we can do this using gen_lowpart_common, do so. Note
|
||||||
that VALUE might be a floating-point constant. */
|
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>
|
2013-12-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
Sandra Loosemore <sandra@codesourcery.com>
|
Sandra Loosemore <sandra@codesourcery.com>
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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…
Reference in New Issue