This fixes various instances of ICEs in dwarf2out_finish when processing the limbo DIE list. With LTO we can end up with limbos with RECORD_TYPE context for example when we partitioned away record-local statics and nothing references the record type itself.
In general it seems safe to not expose LTO (with it's semi-broken debug information support) to this kind of sanity check in limbo DIE processing (I've done some real fixes in this area lately, but some are really hard to tackle if we do not want to make partitioning dependent on dwarf2out internals - we feed dwarf2out with types/decls in sometimes unpredicted order). Another kind of fix that crossed my mind would be iterating over the limbo list repeatedly and emitting origins there on-the-fly, but not sure if we'd not run into more issues that way. LTO bootstrapped and tested on x86_64-unknown-linux-gnu. This seems to be the last ICE caused by a LTO mozilla build with -g. Ok for trunk? Thanks, Richard. 2012-01-02 Richard Guenther <rguent...@suse.de> PR debug/51650 * dwarf2out.c (dwarf2out_finish): When processing LTO IL allow any kind of parents for limbo DIEs. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 182784) +++ gcc/dwarf2out.c (working copy) @@ -22501,15 +22501,22 @@ dwarf2out_finish (const char *filename) else if (TYPE_P (node->created_for)) context = TYPE_CONTEXT (node->created_for); - gcc_assert (context - && (TREE_CODE (context) == FUNCTION_DECL - || TREE_CODE (context) == NAMESPACE_DECL)); + /* With LTO we can end up with limbo DIEs with parents + we never output due to partitioning being done + unaware of things like class-scope statics or functions. */ + gcc_assert (in_lto_p + || (context + && (TREE_CODE (context) == FUNCTION_DECL + || TREE_CODE (context) == NAMESPACE_DECL))); - origin = lookup_decl_die (context); + if (context) + origin = lookup_decl_die (context); + else + origin = comp_unit_die (); if (origin) - add_child_die (origin, die); + add_child_die (origin, die); else - add_child_die (comp_unit_die (), die); + add_child_die (comp_unit_die (), die); } } }