The following fixes an ICE with -flto -ffat-lto-objects -fdebug-types-section -g where optimize_external_refs does not expect to see DW_AT_signature as made "local" by build_abbrev_table(sic!).
This is because we run optimize_external_refs twice in this setup. The fix is to make the second run not pick up "local" DW_AT_signature as external. Alternatively build_abbrev_table could be adjusted to not keep those as DW_AT_signature. It's not even clear to me whether a DW_AT_signature as we output it is valid DWARF ... to quote non-LTO -g: <1><1d>: Abbrev Number: 13 (DW_TAG_structure_type) <1e> DW_AT_name : (indirect string, offset: 0x8b): integral_constant<bool, false> <22> DW_AT_signature : <0x5d> <26> DW_AT_declaration : 1 <26> DW_AT_sibling : <0x48> ... <1><5d>: Abbrev Number: 16 (DW_TAG_structure_type) <5e> DW_AT_name : (indirect string, offset: 0x8b): integral_constant<bool, false> <62> DW_AT_signature : signature: 0x1f6a4ae7cc5a362e <6a> DW_AT_declaration : 1 <6a> DW_AT_sibling : <0x7b> 13 DW_TAG_structure_type [has children] DW_AT_name DW_FORM_strp DW_AT_signature DW_FORM_ref4 16 DW_TAG_structure_type [has children] DW_AT_name DW_FORM_strp DW_AT_signature DW_FORM_ref_sig8 Using DW_AT_specification (as other code in dwarf seems to try doing) seems fishy as well given the refering DIE is DW_AT_declaration... The DWARF spec doesn't seem to explicitely list an appropriate refering attribute type that is applicable here. My favorite kitchen-sink DW_AT_abstract_origin might count ;) Of ocurse the main "issue" is that copy_unworthy_types duplicated this parent into 1d and 5d in the first place (but that's a pure optimization issue?). Not doing that would have avoided the situation in PR87295. But then why should optimize_external_refs_1 have this special code handling DW_AT_signature in the first place if this was not intended... (so even better, kill that and the build_abbrev_table optimization and fix copy_unworthy_types?) Oh, and insert rants of -fdebug-types-section not being used by anybody. Bootstrap & regtest running on x86_64-unknown-linux-gnu, OK? Thanks, Richard. 2019-01-25 Richard Biener <rguent...@suse.de> PR debug/87295 * dwarf2out.c (optimize_external_refs_1): Do not pick up already optimized DW_AT_signature refs. * g++.dg/lto/pr87295_0.C: New testcase. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 268260) +++ gcc/dwarf2out.c (working copy) @@ -8911,7 +8911,11 @@ optimize_external_refs_1 (dw_die_ref die struct external_ref *ref_p; if (is_type_die (die) - && (c = get_AT_ref (die, DW_AT_signature))) + && (c = get_AT_ref (die, DW_AT_signature)) + /* Make sure to not pick up optimized local refs from the + early LTO run of build_abbrev_table which performs the + actual redirection. */ + && c->comdat_type_p) { /* This is a local skeleton; use it for local references. */ ref_p = lookup_external_ref (map, c); Index: gcc/testsuite/g++.dg/lto/pr87295_0.C =================================================================== --- gcc/testsuite/g++.dg/lto/pr87295_0.C (nonexistent) +++ gcc/testsuite/g++.dg/lto/pr87295_0.C (working copy) @@ -0,0 +1,20 @@ +// { dg-lto-do assemble } +// { dg-lto-options { { -flto -ffat-lto-objects -fdebug-types-section -g -std=gnu++17 } } } + +template<typename _Tp, _Tp __v> +struct integral_constant +{ + static constexpr _Tp value = __v; + typedef _Tp value_type; + constexpr operator value_type() const noexcept { return value; } +}; + +typedef integral_constant<bool, false> false_type; + +template<typename...> +struct __or_; + +template<> +struct __or_<> + : public false_type +{ };