Hi! This is on top of the PR78835 patch I've posted yesterday. We ICE on the following testcase reduced from libstdc++ ios_failure.cc. If there are nested comdat types, as B (outer type) and A (inner type) in the testcase, we first move A to a type unit and add there copies of its children, and preserve a skeleton copy of A in the main CU with the originals of their children (i.e. something other DIEs may refer to). Then we try to move B into another type unit, but mishandle the children, the DIE for foo subprogram ends up in the B type unit rather than in the main CU where it belongs. Of course nothing can refer to that there from outside of that type unit.
Either hunk in dwarf2out.c is actually enough to fix the ICE. The second hunk fixes the bug that after the moving of the children etc. we end up with node.old_die == node.new_die, which is obviously wrong. We always want old_die to be the DIE that will be in the type unit while new_die one that will remain in the main CU. The first hunk is an optimization, my understanding is that the creation of the skeleton DIEs is so that uses outside of the type unit (i.e. from the main CU) can actually refer to those DIEs (when we lookup_decl_die etc.; from main CU to type units we can only refer using DW_FORM_ref_sig8 to the type unit's single chosen type die). As break_out_comdat_types and its helpers don't actually adjust random references, for nested types I actually think it is enough to have in the type unit of the outer type just a skeleton unit of the inner type with DW_AT_signature of the type residing in yet another type unit, I think there is no way to refer to its children from that type unit. So there is no need to duplicate the children and we can just move them to the main CU. Bootstrapped/regtested on i686-linux with -fdebug-types-section hacked in common.opt to be the default, ok for trunk? Note Ada bootstrap on x86_64-linux with -fdebug-types-section is still broken, but that is preexisting, not introduced by this patch: .../gcc/gnat1 -gnatwa -quiet -nostdinc -dumpbase g-pehage.adb -auxbase-strip g-pehage.o -O2 -Wextra -Wall -g -fpic -gnatpg -mtune=generic -march=x86-64 -gnatO g-pehage.o g-pehage.adb -o /tmp/ccrAYuNB.s -fdebug-types-section raised STORAGE_ERROR : stack overflow or erroneous memory access 2017-01-19 Jakub Jelinek <ja...@redhat.com> PR debug/79129 * dwarf2out.c (generate_skeleton_bottom_up): For children with comdat_type_p set, just clone them, but keep the children in the original DIE. * g++.dg/debug/dwarf2/pr79129.C: New test. --- gcc/dwarf2out.c.jj 2017-01-18 13:40:09.000000000 +0100 +++ gcc/dwarf2out.c 2017-01-19 10:46:36.297776725 +0100 @@ -7918,6 +7918,19 @@ generate_skeleton_bottom_up (skeleton_ch add_child_die (parent->new_die, c); c = prev; } + else if (c->comdat_type_p) + { + /* This is the skeleton of earlier break_out_comdat_types + type. Clone the existing DIE, but keep the children + under the original (which is in the main CU). */ + dw_die_ref clone = clone_die (c); + + replace_child (c, clone, prev); + generate_skeleton_ancestor_tree (parent); + add_child_die (parent->new_die, c); + c = clone; + continue; + } else { /* Clone the existing DIE, move the original to the skeleton @@ -7936,6 +7949,7 @@ generate_skeleton_bottom_up (skeleton_ch replace_child (c, clone, prev); generate_skeleton_ancestor_tree (parent); add_child_die (parent->new_die, c); + node.old_die = clone; node.new_die = c; c = clone; } --- gcc/testsuite/g++.dg/debug/dwarf2/pr79129.C.jj 2017-01-19 11:15:01.876727938 +0100 +++ gcc/testsuite/g++.dg/debug/dwarf2/pr79129.C 2017-01-19 11:14:25.000000000 +0100 @@ -0,0 +1,12 @@ +/* PR debug/79129 */ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-4 -O2 -fdebug-types-section" } */ + +struct B +{ + struct A { void foo (int &); }; + A *bar (); + ~B () { int a = 1; bar ()->foo (a); } +}; +struct C { ~C (); B c; }; +C::~C () {} Jakub