aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2013-12-11 17:09:17 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2013-12-11 17:09:17 +0000
commitebb99f967b8d4b1c23dfba167e16dd2c6786633a (patch)
tree4ba21c39b0d8a3c5a6bae82fe8579f445e23044e
parent6f4e9cf84204e690b7c32060f8eb7d978bfcf2ca (diff)
downloadgcc-ebb99f967b8d4b1c23dfba167e16dd2c6786633a.zip
gcc-ebb99f967b8d4b1c23dfba167e16dd2c6786633a.tar.gz
gcc-ebb99f967b8d4b1c23dfba167e16dd2c6786633a.tar.bz2
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
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/expmed.c43
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr59134.c16
-rw-r--r--gcc/testsuite/gnat.dg/misaligned_volatile.adb28
5 files changed, 97 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b75f6a5..633aa92 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,15 @@
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>
PR middle-end/23623
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 08ad9e0..3a6c919 100644
--- a/gcc/expmed.c
+++ b/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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 47ac2c3..0de1112 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,4 +1,10 @@
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>
* gcc.dg/pr23623.c: Update to test interaction with C++
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr59134.c b/gcc/testsuite/gcc.c-torture/compile/pr59134.c
new file mode 100644
index 0000000..5268805
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr59134.c
@@ -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;
+}
diff --git a/gcc/testsuite/gnat.dg/misaligned_volatile.adb b/gcc/testsuite/gnat.dg/misaligned_volatile.adb
new file mode 100644
index 0000000..c76975b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/misaligned_volatile.adb
@@ -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;