I believe the real problem here is in place_block_symbol() and
output_object_block().  If DECL_INITIAL is given for an array, then
shouldn't we be taking the size from the initializer?

This patch fixes that problem, and ensures that we get an assembler
error if placement in the block changes.  I've bootstrapped with
Jakub's java change, and the libjava failures are gone.  However, the
checking code shows up failures in gcc.c-torture/execute/20010924-1.c
with "attempt to move .org backwards".  This isn't exactly a
regression as previously we generated bad code silently, but clearly
more work is needed to teach place_block_symbol() how to size
variables properly, or else something is going wrong elsewhere in the
compiler..

        PR libcgj/57074
        * varasm.c (place_block_symbol): Use DECL_INITIAL size for
        variables if available.
        (output_object_block): Likewise.  Use .org for each item in
        section anchor block rather than padding.

Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c        (revision 198274)
+++ gcc/varasm.c        (working copy)
@@ -6979,7 +6989,11 @@
     {
       decl = SYMBOL_REF_DECL (symbol);
       alignment = DECL_ALIGN (decl);
-      size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
+      if (DECL_INITIAL (decl)
+         && DECL_INITIAL (decl) != error_mark_node)
+       size = int_size_in_bytes (TREE_TYPE (DECL_INITIAL (decl)));
+      else
+       size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
       if (flag_asan && asan_protect_global (decl))
        {
          size += asan_red_zone_size (size);
@@ -7095,6 +7109,10 @@
   HOST_WIDE_INT offset;
   tree decl;
   rtx symbol;
+#if HAVE_GNU_AS
+  static int labelno;
+  char buf[30];
+#endif
 
   if (!block->objects)
     return;
@@ -7104,6 +7122,12 @@
   switch_to_section (block->sect);
   assemble_align (block->alignment);
 
+#if HAVE_GNU_AS
+  ASM_GENERATE_INTERNAL_LABEL (buf, "LANCB", labelno);
+  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, buf);
+  ++labelno;
+#endif
+
   /* Define the values of all anchors relative to the current section
      position.  */
   FOR_EACH_VEC_SAFE_ELT (block->anchors, i, symbol)
@@ -7114,7 +7138,14 @@
   FOR_EACH_VEC_ELT (*block->objects, i, symbol)
     {
       /* Move to the object's offset, padding with zeros if necessary.  */
+#if HAVE_GNU_AS
+      fprintf (asm_out_file, "\t.org ");
+      assemble_name_raw (asm_out_file, buf);
+      fprintf (asm_out_file, "+" HOST_WIDE_INT_PRINT_DEC "\n",
+              SYMBOL_REF_BLOCK_OFFSET (symbol));
+#else
       assemble_zeros (SYMBOL_REF_BLOCK_OFFSET (symbol) - offset);
+#endif
       offset = SYMBOL_REF_BLOCK_OFFSET (symbol);
       if (CONSTANT_POOL_ADDRESS_P (symbol))
        {
@@ -7144,7 +7175,11 @@
          HOST_WIDE_INT size;
          decl = SYMBOL_REF_DECL (symbol);
          assemble_variable_contents (decl, XSTR (symbol, 0), false);
-         size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
+         if (DECL_INITIAL (decl)
+             && DECL_INITIAL (decl) != error_mark_node)
+           size = int_size_in_bytes (TREE_TYPE (DECL_INITIAL (decl)));
+         else
+           size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
          offset += size;
          if (flag_asan && asan_protect_global (decl))
            {

-- 
Alan Modra
Australia Development Lab, IBM

Reply via email to