http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48508
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org --- Comment #7 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-12-09 13:17:47 UTC --- (gdb) call debug_dwarf_die (die) DIE 459: DW_TAG_formal_parameter (0x7ffff5befdc0) abbrev id: 22 offset: 459 mark: 1 DW_AT_abstract_origin: die -> 0 (0x7ffff5bef730) DW_AT_location: location descriptor (gdb) call debug_dwarf_die (0x7ffff5bef730) DIE 0: DW_TAG_formal_parameter (0x7ffff5bef730) abbrev id: 0 offset: 0 mark: 2 DW_AT_name: "cx" DW_AT_decl_file: "jsatom.3.ii" (1) DW_AT_decl_line: 58 DW_AT_type: die -> 287 (0x7ffff5bebc30) So the question is why was that DIE not output. The answer is possibly because dwarf2out.c would do so only when a proper debug hook is called from the frontend. The DIE get's generated via #0 gen_formal_parameter_die (node=0x7ffff5b6f5d8, origin=0x0, emit_name_p=1 '\001', context_die=0x7ffff5bf0690) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:16703 #1 0x000000000062e8b6 in gen_decl_die (decl=0x7ffff5b6f5d8, origin=0x0, context_die=0x7ffff5bf0690) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:19576 #2 0x0000000000624ac7 in gen_subprogram_die (decl=0x7ffff5b70d00, context_die=0x7ffff5bec410) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:17496 #3 0x000000000062dfac in gen_decl_die (decl=0x7ffff5b70d00, origin=0x0, context_die=0x7ffff5bec410) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:19489 #4 0x000000000062f48e in dwarf2out_decl (decl=0x7ffff5b70d00) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:19863 #5 0x000000000062321a in dwarf2out_abstract_function (decl=0x7ffff5b70d00) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:16969 #6 0x000000000057316b in gimple_expand_cfg () at /space/rguenther/src/svn/trunk/gcc/cfgexpand.c:4654 so it was created up-front to be used by inline instances. But for some reason we do not mark it for output even though it ends up being used. We are creating a DIE for the same parameter again, via #0 gen_formal_parameter_die (node=0x7ffff5b6f5d8, origin=0x0, emit_name_p=1 '\001', context_die=0x7ffff5bf0cd0) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:16703 #1 0x000000000062e8b6 in gen_decl_die (decl=0x7ffff5b6f5d8, origin=0x0, context_die=0x7ffff5bf0cd0) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:19576 #2 0x0000000000624ac7 in gen_subprogram_die (decl=0x7ffff5b70d00, context_die=0x7ffff5bec410) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:17496 #3 0x000000000062dfac in gen_decl_die (decl=0x7ffff5b70d00, origin=0x0, context_die=0x7ffff5bec410) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:19489 #4 0x000000000062f48e in dwarf2out_decl (decl=0x7ffff5b70d00) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:19863 #5 0x000000000062f4c9 in dwarf2out_function_decl (decl=0x7ffff5b70d00) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:19871 #6 0x00000000006a6b89 in rest_of_handle_final () at /space/rguenther/src/svn/trunk/gcc/final.c:4349 interestingly the 2nd one (not found by lookup_decl_die) is the one that refers to the DIE in question. Guarding it like Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 182154) +++ dwarf2out.c (working copy) @@ -19868,7 +19868,8 @@ dwarf2out_decl (tree decl) static void dwarf2out_function_decl (tree decl) { - dwarf2out_decl (decl); + if (!lookup_decl_die (decl)) + dwarf2out_decl (decl); call_arg_locations = NULL; call_arg_loc_last = NULL; call_site_count = -1; fixes the ICE. Now the question is what guarantees that this does not happen? Should we be able to assert like Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 182154) +++ dwarf2out.c (working copy) @@ -5171,6 +5171,7 @@ equate_decl_number_to_die (tree decl, dw void **slot; slot = htab_find_slot_with_hash (decl_die_table, decl, decl_id, INSERT); + gcc_assert (!*slot || *slot == decl_die); *slot = decl_die; decl_die->decl_id = decl_id; } ? That trivially asserts already at compile-time, without -flto. Or is this an odering issue somehow and the two DIEs should have been created in the opposite order? Or should the DIE reference have been created inbetween the two calls? I realize this has more questions than answers ... :/