re PR target/16407 (Unaligned access to local variables)
authorRichard Sandiford <rsandifo@redhat.com>
Wed, 7 Jul 2004 19:17:05 +0000 (19:17 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 7 Jul 2004 19:17:05 +0000 (19:17 +0000)
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

gcc/ChangeLog
gcc/config/mips/iris6.h
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20040707-1.c [new file with mode: 0644]

index 22e1c66bba6229750f7e938d42a5036c29e472a3..63501dbb810410809c516f299f3a9c30ad35b50a 100644 (file)
@@ -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
index 33d6b09825a1eb405164b4c1fbf25fbcda4dfb32..9730a6c0bcf25ba8fad0005c2317f7d6ea2619fc 100644 (file)
@@ -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)
 
index f3b7bdbed7718f8699418a6335a8395785e96314..f1c42ab909dcd3a14c038383a53a31136eb8cbd1 100644 (file)
@@ -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);
index 8382b026818df5e24fe7e8b32da8cd6a8d2253fc..8e0266a61b63a5a455bcb2edcf6bdf6206531b21 100644 (file)
@@ -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);
 }
index 77ea0e0e32ebe9d13d471fb808281a264587352b..00ddbba1b65693fbcd2f85de6aa9bdfdb1669377 100644 (file)
@@ -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
index 4168a683c5ad70e58ed6b79fba7986b3a8d77fe1..7f91c446592ad7dfa84984b88bf99fa1a712da58 100644 (file)
@@ -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 (file)
index 0000000..6fc15cc
--- /dev/null
@@ -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);
+}