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