http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55395
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2012-12-04
CC| |hubicka at gcc dot gnu.org,
| |jakub at gcc dot gnu.org
Ever Confirmed|0 |1
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-12-04
10:13:06 UTC ---
Reduced testcase:
/* { dg-do compile } */
/* { dg-options "-fdata-sections -g -O2" } */
/* { dg-additional-options "-fstack-protector" { target fstack_protector } } */
extern inline __attribute__ ((__always_inline__))
void *
memcpy (void *__restrict d, const void *__restrict s, __SIZE_TYPE__ l)
{
return __builtin___memcpy_chk (d, s, l, __builtin_object_size (d, 0));
}
void
foo (char *p)
{
static const char q[] = "\n";
memcpy (p, &q, 1);
}
The reason why this fails is IMHO bogus change from
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=187631
void
varpool_remove_node (struct varpool_node *node)
{
symtab_unregister_node ((symtab_node)node);
if (DECL_INITIAL (node->symbol.decl)
&& !DECL_IN_CONSTANT_POOL (node->symbol.decl)
/* Keep vtables for BINFO folding. */
&& !DECL_VIRTUAL_P (node->symbol.decl)
/* dbxout output constant initializers for readonly vars. */
&& (!host_integerp (DECL_INITIAL (node->symbol.decl), 0)
|| !TREE_READONLY (node->symbol.decl)))
DECL_INITIAL (node->symbol.decl) = error_mark_node;
ggc_free (node);
}
(the DECL_INITIAL setting to error_mark_node). I can understand the aim at
saving compile time memory, but this is a wrong thing to do. dwarf2out.c uses
DECL_INITIAL heavily to emit debug info even for optimized away variables.
The exact reason for the error is that we have get_named_section called twice,
once before the varpool_remove_node call, once after it.
The first one is:
#1 0x0000000000cc64dc in get_named_section (decl=0x7ffff19a5850,
name=0x7ffff17fdbf4 ".rodata.q.4121", reloc=0) at ../../gcc/varasm.c:411
#2 0x0000000000cc7d6c in get_variable_section (decl=0x7ffff19a5850,
prefer_noswitch_p=true) at ../../gcc/varasm.c:1030
#3 0x0000000000cc7f88 in get_block_for_decl (decl=0x7ffff19a5850) at
../../gcc/varasm.c:1076
#4 0x0000000000cc8a88 in make_decl_rtl (decl=0x7ffff19a5850) at
../../gcc/varasm.c:1295
#5 0x0000000000cc8e4f in make_decl_rtl_for_debug (decl=0x7ffff19a5850) at
../../gcc/varasm.c:1350
#6 0x0000000000654bea in expand_debug_expr (exp=0x7ffff19a5850) at
../../gcc/cfgexpand.c:2777
#7 0x0000000000657357 in expand_debug_expr (exp=0x7ffff17ed460) at
../../gcc/cfgexpand.c:3358
#8 0x0000000000658b37 in expand_debug_locations () at
../../gcc/cfgexpand.c:3739
#9 0x000000000065b3c5 in gimple_expand_cfg () at ../../gcc/cfgexpand.c:4606
when creating DEBUG_IMPLICIT_PTR for the parameter s. Then varpool_remove_node
is called:
#0 varpool_remove_node (node=0x7ffff19a6410) at ../../gcc/varpool.c:61
#1 0x0000000000cdb98a in varpool_remove_unreferenced_decls () at
../../gcc/varpool.c:406
#2 0x0000000000cdbb07 in varpool_output_variables () at
../../gcc/varpool.c:440
#3 0x0000000000686a00 in compile () at ../../gcc/cgraphunit.c:2044
#4 0x0000000000686b7a in finalize_compilation_unit () at
../../gcc/cgraphunit.c:2120
and finally get_named_section again:
#1 0x0000000000cc64dc in get_named_section (decl=0x7ffff19a5850,
name=0x7ffff17fdbf4 ".rodata.q.4121", reloc=0) at ../../gcc/varasm.c:411
#2 0x0000000000cc7d6c in get_variable_section (decl=0x7ffff19a5850,
prefer_noswitch_p=true) at ../../gcc/varasm.c:1030
#3 0x0000000000cc7f88 in get_block_for_decl (decl=0x7ffff19a5850) at
../../gcc/varasm.c:1076
#4 0x0000000000cc8a88 in make_decl_rtl (decl=0x7ffff19a5850) at
../../gcc/varasm.c:1295
#5 0x0000000000cc8e4f in make_decl_rtl_for_debug (decl=0x7ffff19a5850) at
../../gcc/varasm.c:1350
#6 0x00000000006f4d33 in rtl_for_decl_location (decl=0x7ffff19a5850) at
../../gcc/dwarf2out.c:15150
#7 0x00000000006f503f in add_location_or_const_value_attribute
(die=0x7ffff1805be0, decl=0x7ffff19a5850, cache_p=false, attr=DW_AT_location)
at ../../gcc/dwarf2out.c:15244
#8 0x0000000000709d9b in dwarf2out_finish (filename=0x7fffffffe58b
"pr55395.i") at ../../gcc/dwarf2out.c:23218
#9 0x0000000000a3e2ce in compile_file () at ../../gcc/toplev.c:600
In the first case, DECL_INITIAL is not NULL, nor error_mark_node, nor zero
initializer, so rodata.q.4121 is assumed to be a read-only section, in the
second case DECL_INITIAL of q is already error_mark_node and thus rodata.q.4121
is assumed to be a bss section, therefore a section flags conflict. In the
case of array initialized with a constant string right now the initializer
won't be useful, but I guess we could emit DW_OP_GNU_implicit_pointer in that
case, pointing to a DW_OP_implicit_value initialized artificial object. But
there are tons of cases where DECL_INITIAL is even successfully used at
dwarf2out_finish time, e.g. during the deferred location processing. So, if
you want to save memory, please do that solely if not emitting debug info.
So, I'd suggest replacing the
/* dbxout output constant initializers for readonly vars. */
&& (!host_integerp (DECL_INITIAL (node->symbol.decl), 0)
|| !TREE_READONLY (node->symbol.decl)))
part with
&& write_symbols == NO_DEBUG)
or ammending it with
/* dwarf2out.c uses DECL_INITIAL even on optimized away decls,
very late during compilation. */
&& (write_symbols != DWARF2_DEBUG && write_symbols !=
VMS_AND_DWARF2_DEBUG)