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