aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-07-07 19:17:05 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-07-07 19:17:05 +0000
commit48b2e0a72e5e297ad921662683c1f5d61d0e95b1 (patch)
treecde4f0026ad12e34f4ad315b43bf7ad37c6352f3 /gcc
parent477eff96027c33292018e0c73131bfa4556a1602 (diff)
downloadgcc-48b2e0a72e5e297ad921662683c1f5d61d0e95b1.zip
gcc-48b2e0a72e5e297ad921662683c1f5d61d0e95b1.tar.gz
gcc-48b2e0a72e5e297ad921662683c1f5d61d0e95b1.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/mips/iris6.h5
-rw-r--r--gcc/config/mips/mips-protos.h3
-rw-r--r--gcc/config/mips/mips.c25
-rw-r--r--gcc/config/mips/mips.h7
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040707-1.c12
7 files changed, 58 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 22e1c66..63501db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2004-07-07 Richard Sandiford <rsandifo@redhat.com>
+
+ 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 <dave.anglin@nrc-cnrc.gc.ca>
PR c/16392
diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h
index 33d6b09..9730a6c 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 f3b7bdbed..f1c42ab 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 8382b02..8e0266a 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 77ea0e0..00ddbba 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 4168a68..7f91c44 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-07-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.c-torture/execute/20040707-1.c: New test.
+
2004-07-06 Richard Sandiford <rsandifo@redhat.com>
* 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 0000000..6fc15cc
--- /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);
+}