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;

Reply via email to