Message ID | 5508874D.70008@redhat.com |
---|---|
State | New |
Headers | show |
On 03/17/2015 03:58 PM, Aldy Hernandez wrote: > The problem is that, for -fno-implicit-templates, the decl is now > DECL_EXTERNAL, which means we never equate this new "DIE with > DW_AT_specification" to the DECL. That is, we never fall through here: > > else if (!DECL_EXTERNAL (decl)) > { > HOST_WIDE_INT cfa_fb_offset; > > struct function *fun = DECL_STRUCT_FUNCTION (decl); > > if (!old_die || !get_AT (old_die, DW_AT_inline)) > equate_decl_number_to_die (decl, subr_die); > > However, when we call gen_subprogram_die() the third time through the > outlining_inline_function hook (late debug), we again try to add a > DW_AT_specification to the DIE cached from the first time around, but > this time we ICE because we're not supposed to have multiple > DW_AT_specification's pointing to the same DIE (the old original DIE). Why are we outlining a DECL_EXTERNAL function? Incidentally, > /* If we have no location information, this must be a > partially generated DIE from early dwarf generation. > Fall through and generate it. */ Why aren't we checking dumped_early here? Jason
On 03/17/2015 07:12 PM, Jason Merrill wrote: > On 03/17/2015 03:58 PM, Aldy Hernandez wrote: >> The problem is that, for -fno-implicit-templates, the decl is now >> DECL_EXTERNAL, which means we never equate this new "DIE with >> DW_AT_specification" to the DECL. That is, we never fall through here: >> >> else if (!DECL_EXTERNAL (decl)) >> { >> HOST_WIDE_INT cfa_fb_offset; >> >> struct function *fun = DECL_STRUCT_FUNCTION (decl); >> >> if (!old_die || !get_AT (old_die, DW_AT_inline)) >> equate_decl_number_to_die (decl, subr_die); >> >> However, when we call gen_subprogram_die() the third time through the >> outlining_inline_function hook (late debug), we again try to add a >> DW_AT_specification to the DIE cached from the first time around, but >> this time we ICE because we're not supposed to have multiple >> DW_AT_specification's pointing to the same DIE (the old original DIE). > > Why are we outlining a DECL_EXTERNAL function? SRA is analyzing Object<int>::Method() and noticing that `this' is never used, so it's trying to rewrite the call to avoid passing `this' (by creating a clone). SRA has no restrictions on whether a function is DECL_EXTERNAL. For that matter, the SRA pass is called on all functions that have a gimple body, irregardless of DECL_EXTERNAL, courtesy of the pass manager: if (node->has_gimple_body_p ()) callback (DECL_STRUCT_FUNCTION (node->decl), data); ...and since Object<int>::Method() has a gimple body even though it is marked DECL_EXTERNAL...we get the call into dwarf2out_abstract_decl. > > Incidentally, > >> /* If we have no location information, this must be a >> partially generated DIE from early dwarf generation. >> Fall through and generate it. */ > > Why aren't we checking dumped_early here? Good point. I'll add an assert. Aldy
On 03/18/2015 11:51 AM, Aldy Hernandez wrote: > On 03/17/2015 07:12 PM, Jason Merrill wrote: >> Why are we outlining a DECL_EXTERNAL function? > > SRA has no restrictions on whether a function is DECL_EXTERNAL. Aha. So it seems that DECL_EXTERNAL is the wrong gate for equate_decl_number_to_die here. I think the rule we want is that if we don't already have a non-declaration DIE for a function, we should equate the new DIE. Let's remove the existing calls and replace them with a single conditional call before the if (declaration). Incidentally, > /* A declaration that has been previously dumped needs no > additional information. */ > if (dumped_early && declaration) > return; Do we need to check dumped_early here? I would think that any declaration that has an old_die needs no additional information. Jason
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 86815be..c7345d9 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -18809,6 +18809,8 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)), TYPE_UNQUALIFIED, context_die); } + if (early_dwarf_dumping) + equate_decl_number_to_die (decl, subr_die); } } /* Anything else... create a brand new DIE. */