2013-12-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
authoredlinger <edlinger@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Dec 2013 17:09:17 +0000 (17:09 +0000)
committeredlinger <edlinger@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Dec 2013 17:09:17 +0000 (17:09 +0000)
        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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205898 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expmed.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr59134.c [new file with mode: 0644]
gcc/testsuite/gnat.dg/misaligned_volatile.adb [new file with mode: 0644]

index b75f6a5..633aa92 100644 (file)
@@ -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
index 08ad9e0..3a6c919 100644 (file)
@@ -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.  */
index 47ac2c3..0de1112 100644 (file)
@@ -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 (file)
index 0000000..5268805
--- /dev/null
@@ -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 (file)
index 0000000..c76975b
--- /dev/null
@@ -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;