[Bug debug/87428] New: "Missed" inline instances cause bogus DWARF to be emitted
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Sep 25 08:46:00 GMT 2018
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).
More information about the Gcc-bugs
mailing list