http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54519

             Bug #: 54519
           Summary: [4.6/4.7/4.8 Regression] Debug info quality regression
                    due to (pointless) partial inlining
    Classification: Unclassified
           Product: gcc
           Version: 4.7.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: ja...@gcc.gnu.org
                CC: aol...@gcc.gnu.org, hubi...@gcc.gnu.org,
                    jan.kratoch...@redhat.com


extern void bar (int);

static int
foo (int x, int y)
{
  if (x)
    {
      bar (x);
      bar (x);
      bar (x);
      bar (x);
      bar (x);
    }
  return y;
}

#ifndef INL
void *p = (void *) foo;
#else
int
baz1 (int x, int y)
{
  return foo (x, y);
}

int
baz2 (int x, int y)
{
  return foo (x, y);
}
#endif

at -g -O2 results in partial inlining (even when without -DINL it has no
callers at all, can that be changed?), and immediately inlining it back.  In
4.7 (before
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=188981
change) in debuginfo we actually end up with terribly confusing
DW_TAG_inlined_subroutine of the same abstract origin as the current function,
r188981 improves that slightly, so it is actually DW_TAG_lexical_block instead.
But still, for one of the parameters we end up with unnecessary another
location list for it (it would be nice if we could merge them) and more
importantly, for the second parameter we end up with another DW_TAG_variable
with abstract origin of its origin, but actually no location list at all.
This is the main reason why this PR is filed.
The VAR_DECL is created by copy_arguments_for_versioning, with copy_decl_to_var
there, just in case the var would be used as local temporary.  It isn't used in
this case, so it ends up with no location at all (we want to use the location
of the outer argument in that case), if it was used as a local temporary, we'd
still want to use the outer parameter location before it is initialized.

And completely another case is when foo.part.N isn't inlined back, -g -O2 -DINL
shows that case.  Then y still doesn't have any location info.

Either we could make inlining smarter about the case where fnsplitted function
is being inlined back into the main body (essentially try to remap the inline
fn parameter or these special outer block vars back to the outer function's
parameters or variables), or perhaps at least add a debug source stmt at the
beginning of the foo.part.* which would say that the special var created by
copy_arguments_for_versioning lives in the caller's parameter (like we do for
say IPA cp).

Reply via email to