This fixes another case where we end up with duplicate stub DIEs and thus build_abbrev_table trying to adjust a DW_AT_signature ref to a local DIE. This happens when we have two unworthy DIEs from different type units rooted in stub DIEs themselves. Here copy_ancestor_tree records the stubs as original DIE that gets copied failing to see we already copied the thing.
Bootstrap & regtest running on x86_64-unknown-linux-gnu. OK? Thanks, Richard. 2019-02-01 Richard Biener <rguent...@suse.de> PR debug/87295 * dwarf2out.c (copy_ancestor_tree): Register non-stubs as orig. * g++.dg/debug/dwarf2/pr87295.C: New testcase. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 268446) +++ gcc/dwarf2out.c (working copy) @@ -8169,6 +8169,11 @@ copy_ancestor_tree (dw_die_ref unit, dw_ decl_table_entry **slot = NULL; struct decl_table_entry *entry = NULL; + /* If DIE refers to a stub unfold that so we get the appropriate + DIE registered as orig in decl_table. */ + if (dw_die_ref c = get_AT_ref (die, DW_AT_signature)) + die = c; + if (decl_table) { /* Check if the entry has already been copied to UNIT. */ Index: gcc/testsuite/g++.dg/debug/dwarf2/pr87295.C =================================================================== --- gcc/testsuite/g++.dg/debug/dwarf2/pr87295.C (nonexistent) +++ gcc/testsuite/g++.dg/debug/dwarf2/pr87295.C (working copy) @@ -0,0 +1,22 @@ +// { dg-additional-options "-fdebug-types-section" } +// { dg-require-effective-target c++11 } + +struct A {}; +namespace N { + struct B { + using C = struct H {}; + using D = A; + }; +} +struct E : N::B { + typedef C C; +}; +namespace N { + struct F { + E::C d; + E::D h; + }; +} +struct G { + N::F i; +} j;