https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87428
Bug ID: 87428 Summary: "Missed" inline instances cause bogus DWARF to be emitted Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org Target Milestone: --- Currently inlined_function_outer_scope_p keys on BLOCK_SOURCE_LOCATION but instrumenting tree-inline like Index: gcc/tree-inline.c =================================================================== --- gcc/tree-inline.c (revision 264564) +++ gcc/tree-inline.c (working copy) @@ -4527,10 +4527,11 @@ expand_call_inline (basic_block bb, gimp not refer to them in any way to not break GC for locations. */ if (gimple_block (stmt)) { + location_t loc = LOCATION_LOCUS (gimple_location (stmt)); id->block = make_node (BLOCK); BLOCK_ABSTRACT_ORIGIN (id->block) = fn; - BLOCK_SOURCE_LOCATION (id->block) - = LOCATION_LOCUS (gimple_location (stmt)); + BLOCK_SOURCE_LOCATION (id->block) = loc; + gcc_checking_assert (loc != UNKNOWN_LOCATION); prepend_lexical_block (gimple_block (stmt), id->block); } shows we hit this a lot, for example in g++.dg/pr54655.C where one destructor call doesn't have a location. Slightly altering the testcase to extern "C" class A { }; int cnt; template <typename T> class B:A { public: B (int *, T); ~B () { volatile int x = 1; cnt+=x; } }; bool a; inline void fn1 () { switch (0) case 0: { B <int*> b (0, 0); if (a) break; } } void fn2 () { fn1 (); } shows the following debug information generated for the respective inline instance of B::~B (): <1><e4>: Abbrev Number: 15 (DW_TAG_subprogram) <e5> DW_AT_specification: <0xac> <e9> DW_AT_object_pointer: <0xf2> <ed> DW_AT_inline : 2 (declared as inline but ignored) <ee> DW_AT_sibling : <0x111> ... <4><1cc>: Abbrev Number: 30 (DW_TAG_lexical_block) <1cd> DW_AT_abstract_origin: <0xe4> <1d1> DW_AT_low_pc : 0x38 <1d9> DW_AT_high_pc : 0x12 <1e1> DW_AT_sibling : <0x211> <5><1e5>: Abbrev Number: 28 (DW_TAG_formal_parameter) <1e6> DW_AT_abstract_origin: <0xf2> <1ea> DW_AT_location : 0x29 (location list) <1ee> DW_AT_GNU_locviews: 0x27 <5><1f2>: Abbrev Number: 29 (DW_TAG_lexical_block) <1f3> DW_AT_abstract_origin: <0x104> <1f7> DW_AT_low_pc : 0x38 <1ff> DW_AT_high_pc : 0x12 <6><207>: Abbrev Number: 26 (DW_TAG_variable) <208> DW_AT_abstract_origin: <0x105> <20c> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24) <6><20f>: Abbrev Number: 0 <5><210>: Abbrev Number: 0 ... which violates the constraints on DW_AT_abstract_origin (same tag requirement). I couldn't find any wording that DW_TAG_formal_parameter shouldn't be child of a DW_TAG_lexical_block but at least that looks odd. gdb gets confused here because it processes DW_TAG_formal_paramters of DW_TAG_subprogram/DW_TAG_inlined_subroutine differently from other places when LTO pulls in an inline instance from a CU with a different source language (see PR87362). I think that ultimately we want to see a DW_TAG_inlined_subroutine here and thus inlined_function_outer_scope_p return true. I've tried to change that to simply look at BLOCK_ABSTRACT_ORIGIN instead but that now breaks with the recent addition of another kind of DEBUG stmts... (NOTE_INSN_INLINE_ENTRY keying on a location and then relying on getting the correct block back out). So I don't have a good solution ready here (apart from trying to have locations for all calls that get inlined... and eventually going the !gimple_block (stmt) way if we don't).