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).

Reply via email to