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)