A patch from Honza not LTO streaming DECL_ORIGINAL_TYPE ends up ICEing during LTO bootstrap because we end up not re-using the DIE we create late during LTRANS for a subprogram because its parent is a namespace rather than a CU DIE (or a module).
I'm wondering of the general reason why we enforce (inconsistently) "We always want the DIE for this function that has the *_pc attributes to be under comp_unit_die so the debugger can find it." We indeed generate a specification DIE rooted at the CU in addition to the declaration DIE inside the namespace for sth as simple as namespace Foo { void foo () {} } anyhow - the comment also says "We also need to do this [re-use the DIE] for abstract instances of inlines, since the spec requires the out-of-line copy to have the same parent.". Not sure what condition this part of the comment applies to. So my fix is to move the || get_AT (old_die, DW_AT_abstract_origin) check I added for early LTO debug to a global override - forcing DIE re-use for any DIE with an abstract origin set. That is, all concrete instances are fine where they are. That also avoids double-indirection DW_AT_specification -> DW_AT_abstract_origin -> DIE. But as said, I wonder about the overall condition, esp. the DW_TAG_module special-casing (but not at the same time special-casing DW_TAG_namespace or DW_TAG_partial_unit). LTO bootstrap is in progress on x86_64-unknown-linux-gnu. OK if that succeeds? Thanks, Richard. 2018-06-26 Richard Biener <rguent...@suse.de> * dwarf2out.c (gen_subprogram_die): Always re-use DIEs with an DW_AT_abstract_origin attribute. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 262132) +++ gcc/dwarf2out.c (working copy) @@ -22780,26 +22780,25 @@ gen_subprogram_die (tree decl, dw_die_re apply; we just use the old DIE. */ expanded_location s = expand_location (DECL_SOURCE_LOCATION (decl)); struct dwarf_file_data * file_index = lookup_filename (s.file); - if ((is_cu_die (old_die->die_parent) - /* This condition fixes the inconsistency/ICE with the - following Fortran test (or some derivative thereof) while - building libgfortran: + if (((is_cu_die (old_die->die_parent) + /* This condition fixes the inconsistency/ICE with the + following Fortran test (or some derivative thereof) while + building libgfortran: - module some_m - contains - logical function funky (FLAG) - funky = .true. - end function - end module - */ - || (old_die->die_parent - && old_die->die_parent->die_tag == DW_TAG_module) - || context_die == NULL) + module some_m + contains + logical function funky (FLAG) + funky = .true. + end function + end module + */ + || (old_die->die_parent + && old_die->die_parent->die_tag == DW_TAG_module) + || context_die == NULL) && (DECL_ARTIFICIAL (decl) /* The location attributes may be in the abstract origin which in the case of LTO might be not available to look at. */ - || get_AT (old_die, DW_AT_abstract_origin) || (get_AT_file (old_die, DW_AT_decl_file) == file_index && (get_AT_unsigned (old_die, DW_AT_decl_line) == (unsigned) s.line) @@ -22807,6 +22806,10 @@ gen_subprogram_die (tree decl, dw_die_re || s.column == 0 || (get_AT_unsigned (old_die, DW_AT_decl_column) == (unsigned) s.column))))) + /* With LTO if there's an abstract instance for + the old DIE, this is a concrete instance and + thus re-use the DIE. */ + || get_AT (old_die, DW_AT_abstract_origin)) { subr_die = old_die;