OSDN Git Service

PR middle-end/7847
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Dec 2003 07:15:31 +0000 (07:15 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Dec 2003 07:15:31 +0000 (07:15 +0000)
* expr.c (expand_expr) [normal_inner_ref]: When 'offset' is non-zero,
do not recheck that 'op0' is a MEM.  Move comment.  When testing for
unaligned objects, take also into account the alignment of 'op0' and
'mode1' if 'op0' is a MEM.

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

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/unaligned-1.c [new file with mode: 0644]

index 02f466d..d109ceb 100644 (file)
@@ -1,3 +1,11 @@
+2003-12-01  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR middle-end/7847
+       * expr.c (expand_expr) [normal_inner_ref]: When 'offset' is non-zero,
+       do not recheck that 'op0' is a MEM.  Move comment.  When testing for
+       unaligned objects, take also into account the alignment of 'op0' and
+       'mode1' if 'op0' is a MEM.
+
 2003-12-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
 
        * doc/c-tree.texi (Function Bodies): Update HANDLER documentation.
index 79b9486..c013785 100644 (file)
@@ -7153,10 +7153,9 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
              offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
 #endif
 
-           /* A constant address in OP0 can have VOIDmode, we must not try
-              to call force_reg for that case.  Avoid that case.  */
-           if (GET_CODE (op0) == MEM
-               && GET_MODE (op0) == BLKmode
+           if (GET_MODE (op0) == BLKmode
+               /* A constant address in OP0 can have VOIDmode, we must
+                  not try to call force_reg in that case.  */
                && GET_MODE (XEXP (op0, 0)) != VOIDmode
                && bitsize != 0
                && (bitpos % bitsize) == 0
@@ -7213,7 +7212,10 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode,
               fetch it as a bit field.  */
            || (mode1 != BLKmode
                && (((TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
-                     || (bitpos % GET_MODE_ALIGNMENT (mode) != 0))
+                     || (bitpos % GET_MODE_ALIGNMENT (mode) != 0)
+                     || (GET_CODE (op0) == MEM
+                         && (MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
+                             || (bitpos % GET_MODE_ALIGNMENT (mode1) != 0))))
                     && ((modifier == EXPAND_CONST_ADDRESS
                          || modifier == EXPAND_INITIALIZER)
                         ? STRICT_ALIGNMENT
index 10d1d8e..417272f 100644 (file)
@@ -1,3 +1,7 @@
+2003-12-01  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * gcc.dg/unaligned-1.c: New test.
+
 2003-11-30  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/9849
diff --git a/gcc/testsuite/gcc.dg/unaligned-1.c b/gcc/testsuite/gcc.dg/unaligned-1.c
new file mode 100644 (file)
index 0000000..5df1b37
--- /dev/null
@@ -0,0 +1,49 @@
+/* PR middle-end/7847 */
+/* Originator: <jk@tools.de> */
+/* { dg-do run } */
+
+/* This used to fail on SPARC at runtime because of
+   an unaligned memory access.  */
+
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+
+typedef struct {
+    uint32_t address;
+    uint16_t size;
+} __attribute__ ((packed)) sml_agl_data_t;
+
+typedef struct {
+  sml_agl_data_t data[9];
+} __attribute__ ((packed)) sml_agli_t;
+
+typedef struct {
+  sml_agli_t sml_agli;
+} __attribute__ ((packed)) dsi_t;
+
+typedef struct {
+  int a;
+  dsi_t dsi_pack;
+} dvd_priv_t;
+
+int dvd_read_sector(dvd_priv_t *d, unsigned char* data)
+{
+  int i, skip=0;
+
+  for (i=0; i < 9; i++)
+    if ((skip=d->dsi_pack.sml_agli.data[i].address) != 0)
+      break;
+
+  return skip;
+}
+
+int main(void)
+{
+  static dvd_priv_t dvd_priv;
+  dvd_read_sector(&dvd_priv, 0);
+  return 0;
+}