https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96471
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- So the DIEs in question are DIE 0: DW_TAG_subrange_type (0x7ffff69f3e10) abbrev id: 0 offset: 0 mark: 1 DW_AT_type: die -> 0 (0x7ffff69f3eb0) DW_AT_upper_bound: die -> 0 (0x7ffff69f30f0) refering to DIE 0: DW_TAG_variable (0x7ffff69f30f0) abbrev id: 0 offset: 0 mark: 0 DW_AT_type: die -> 0 (0x7ffff69d1d70) DW_AT_artificial: 1 where the subrange type is part of a type unit. I think type units do not work this way and a type die like this should disqualify the whole thing from becoming externalized into a type unit in the first place? There is should_move_die_to_comdat which already excludes DIEs containing subprogram definitions, shouldn't all references to non-type non-declaration DIEs also prevent a DIE from being externalized? So for the specific case that's too early(?), after comdat breakout we still see DIE 0: DW_TAG_array_type (0x7ffff69f8140) abbrev id: 0 offset: 0 mark: 0 DW_AT_type: die -> 0 (0x7ffff69f8000) DIE 0: DW_TAG_subrange_type (0x7ffff69f8190) abbrev id: 0 offset: 0 mark: 0 DW_AT_type: die -> 0 (0x7ffff69f8050) DW_AT_upper_bound: location descriptor: (0x7ffff69d1eb0) DW_OP_GNU_variable_value die -> 0 (0x7ffff69f30f0), 0 but then resolve_addr this into a direct DIE ref which eventually copy_decls_walk would handle. There's also note_variable_value doing some location frobbing from decls to DIEs which is done after comdat breakout and which would expose more such situations, so re-ordering that would make sense. Note I think that even location lists are unwanted in type units. Unfortunately the DWARF standard doesn't list what is and what is not allowed in type units. Eventually one could strip the type unit off those unsupported constructs and instead "complete" them in the main unit somehow. Since resolve_addr runs only at dwarf2out_finish time we need to look at the location case either disqualifying stuff or doing magic in copy_decls_for_unworthy_types.