From: Richard Sandiford Date: Wed, 7 Jul 2004 19:17:05 +0000 (+0000) Subject: re PR target/16407 (Unaligned access to local variables) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=48b2e0a72e5e297ad921662683c1f5d61d0e95b1;p=gcc.git re PR target/16407 (Unaligned access to local variables) PR target/16407 * config/mips/mips-protos.h (mips_declare_common_object): Declare. * config/mips/mips.c (mips_declare_common_object): New function, mostly split out from... (mips_output_aligned_decl_common): ...here. * config/mips/mips.h (ASM_OUTPUT_LOCAL): Remove in favor of... (ASM_OUTPUT_ALIGNED_LOCAL): ...this new definition. * config/mips/iris6.h (ASM_OUTPUT_ALIGNED_LOCAL): Undefine this rather than ASM_OUTPUT_LOCAL. Call mips_declare_common_object. From-SVN: r84219 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 22e1c66bba6..63501dbb810 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2004-07-07 Richard Sandiford + + PR target/16407 + * config/mips/mips-protos.h (mips_declare_common_object): Declare. + * config/mips/mips.c (mips_declare_common_object): New function, + mostly split out from... + (mips_output_aligned_decl_common): ...here. + * config/mips/mips.h (ASM_OUTPUT_LOCAL): Remove in favor of... + (ASM_OUTPUT_ALIGNED_LOCAL): ...this new definition. + * config/mips/iris6.h (ASM_OUTPUT_ALIGNED_LOCAL): Undefine this + rather than ASM_OUTPUT_LOCAL. Call mips_declare_common_object. + 2004-07-07 John David Anglin PR c/16392 diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h index 33d6b09825a..9730a6c0bcf 100644 --- a/gcc/config/mips/iris6.h +++ b/gcc/config/mips/iris6.h @@ -357,7 +357,7 @@ do \ while (0) /* ??? SGI assembler gives warning whenever .lcomm is used. */ -#undef ASM_OUTPUT_LOCAL +#undef ASM_OUTPUT_ALIGNED_LOCAL #define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \ do \ { \ @@ -369,7 +369,8 @@ do \ ASM_OUTPUT_SKIP (STREAM, SIZE); \ } \ else \ - mips_declare_object (STREAM, NAME, "\n\t.lcomm\t", ",%u\n", (int)(SIZE)); \ + mips_declare_common_object (STREAM, NAME, "\n\t.lcomm\t", \ + SIZE, ALIGN, false); \ } \ while (0) diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index f3b7bdbed77..f1c42ab909d 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -166,6 +166,9 @@ extern void mips_output_aligned_bss (FILE *, tree, const char *, extern void mips_output_aligned_decl_common (FILE *, tree, const char *, unsigned HOST_WIDE_INT, unsigned int); +extern void mips_declare_common_object (FILE *, const char *, + const char *, unsigned HOST_WIDE_INT, + unsigned int, bool); extern void mips_declare_object (FILE *, const char *, const char *, const char *, ...); extern void mips_declare_object_name (FILE *, const char *, tree); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 8382b026818..8e0266a61b6 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -5987,17 +5987,32 @@ mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name, ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n", size); } - else if (TARGET_SGI_O32_AS) + else + /* The SGI o32 assembler doesn't accept an alignment. */ + mips_declare_common_object (stream, name, "\n\t.comm\t", + size, align, !TARGET_SGI_O32_AS); +} + +/* Declare a common object of SIZE bytes using asm directive INIT_STRING. + NAME is the name of the object and ALIGN is the required alignment + in bytes. TAKES_ALIGNMENT_P is true if the directive takes a third + alignment argument. */ + +void +mips_declare_common_object (FILE *stream, const char *name, + const char *init_string, + unsigned HOST_WIDE_INT size, + unsigned int align, bool takes_alignment_p) +{ + if (!takes_alignment_p) { - /* The SGI o32 assembler doesn't accept an alignment, so round up - the size instead. */ size += (align / BITS_PER_UNIT) - 1; size -= size % (align / BITS_PER_UNIT); - mips_declare_object (stream, name, "\n\t.comm\t", + mips_declare_object (stream, name, init_string, "," HOST_WIDE_INT_PRINT_UNSIGNED "\n", size); } else - mips_declare_object (stream, name, "\n\t.comm\t", + mips_declare_object (stream, name, init_string, "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", size, align / BITS_PER_UNIT); } diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 77ea0e0e32e..00ddbba1b65 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -3189,9 +3189,10 @@ while (0) /* This says how to define a local common symbol (ie, not visible to linker). */ -#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \ - mips_declare_object (STREAM, NAME, "\n\t.lcomm\t", ",%u\n", (int)(SIZE)) - +#ifndef ASM_OUTPUT_ALIGNED_LOCAL +#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \ + mips_declare_common_object (STREAM, NAME, "\n\t.lcomm\t", SIZE, ALIGN, false) +#endif /* This says how to output an external. It would be possible not to output anything and let undefined symbol become external. However diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4168a683c5a..7f91c446592 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-07-07 Richard Sandiford + + * gcc.c-torture/execute/20040707-1.c: New test. + 2004-07-06 Richard Sandiford * gcc.c-torture/execute/20040706-1.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/20040707-1.c b/gcc/testsuite/gcc.c-torture/execute/20040707-1.c new file mode 100644 index 00000000000..6fc15cc24a7 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20040707-1.c @@ -0,0 +1,12 @@ +struct s { char c1, c2; }; +void foo (struct s s) +{ + static struct s s1; + s1 = s; +} +int main () +{ + static struct s s2; + foo (s2); + exit (0); +}