From: Eric Botcazou Date: Mon, 1 Dec 2003 07:15:31 +0000 (+0100) Subject: re PR middle-end/7847 (pragma pack / attribute(packed): unaligned access to packed... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e82407b5bb381e6940f8d4f1a4c218146acc1524;p=gcc.git re PR middle-end/7847 (pragma pack / attribute(packed): unaligned access to packed structure) 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. From-SVN: r74092 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 02f466d2ca7..d109cebb454 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-12-01 Eric Botcazou + + 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 * doc/c-tree.texi (Function Bodies): Update HANDLER documentation. diff --git a/gcc/expr.c b/gcc/expr.c index 79b94867f6b..c01378515f6 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 10d1d8e67d9..417272fdf70 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-12-01 Eric Botcazou + + * gcc.dg/unaligned-1.c: New test. + 2003-11-30 Mark Mitchell 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 index 00000000000..5df1b37e363 --- /dev/null +++ b/gcc/testsuite/gcc.dg/unaligned-1.c @@ -0,0 +1,49 @@ +/* PR middle-end/7847 */ +/* Originator: */ +/* { 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; +}