re PR debug/37801 (DWARF output for inlined functions doesn't always use DW_TAG_inlined_subroutine)
Fix for PR debug/37801 gcc/ChangeLog: * gcc/dwarf2out.c (gen_inlined_subroutine_die): Concentrate on generating inlined subroutine die only. We shouldn't be called for anything else. (gen_block_die): Don't generate inline subroutine debug info for abstract blocks. gcc/testsuite/ChangeLog: * gcc/testsuite/gcc.dg/debug/20020224-1.c: Adjust the comment. Make sure to trigger inlining optimizations. * gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c: New test. From-SVN: r150796
This commit is contained in:
parent
e9dcb5db7d
commit
5782bb7ab9
5 changed files with 123 additions and 20 deletions
|
@ -1,3 +1,11 @@
|
|||
2009-08-16 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
* gcc/dwarf2out.c (gen_inlined_subroutine_die): Concentrate on
|
||||
generating inlined subroutine die only. We shouldn't be
|
||||
called for anything else.
|
||||
(gen_block_die): Don't generate inline subroutine debug info for
|
||||
abstract blocks.
|
||||
|
||||
2009-08-15 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
* graphite-poly.c (print_pbb): Print PBB index.
|
||||
|
|
|
@ -15003,7 +15003,13 @@ gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
|
|||
static void
|
||||
gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
|
||||
{
|
||||
tree decl = block_ultimate_origin (stmt);
|
||||
tree decl;
|
||||
|
||||
/* The instance of function that is effectively being inlined shall not
|
||||
be abstract. */
|
||||
gcc_assert (! BLOCK_ABSTRACT (stmt));
|
||||
|
||||
decl = block_ultimate_origin (stmt);
|
||||
|
||||
/* Emit info for the abstract instance first, if we haven't yet. We
|
||||
must emit this even if the block is abstract, otherwise when we
|
||||
|
@ -15024,20 +15030,6 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
|
|||
decls_for_scope (stmt, subr_die, depth);
|
||||
current_function_has_inlines = 1;
|
||||
}
|
||||
else
|
||||
/* We may get here if we're the outer block of function A that was
|
||||
inlined into function B that was inlined into function C. When
|
||||
generating debugging info for C, dwarf2out_abstract_function(B)
|
||||
would mark all inlined blocks as abstract, including this one.
|
||||
So, we wouldn't (and shouldn't) expect labels to be generated
|
||||
for this one. Instead, just emit debugging info for
|
||||
declarations within the block. This is particularly important
|
||||
in the case of initializers of arguments passed from B to us:
|
||||
if they're statement expressions containing declarations, we
|
||||
wouldn't generate dies for their abstract variables, and then,
|
||||
when generating dies for the real variables, we'd die (pun
|
||||
intended :-) */
|
||||
gen_lexical_block_die (stmt, context_die, depth);
|
||||
}
|
||||
|
||||
/* Generate a DIE for a field in a record, or structure. */
|
||||
|
@ -15666,7 +15658,23 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
|
|||
if (must_output_die)
|
||||
{
|
||||
if (inlined_func)
|
||||
gen_inlined_subroutine_die (stmt, context_die, depth);
|
||||
{
|
||||
/* If STMT block is abstract, that means we have been called
|
||||
indirectly from dwarf2out_abstract_function.
|
||||
That function rightfully marks the descendent blocks (of
|
||||
the abstract function it is dealing with) as being abstract,
|
||||
precisely to prevent us from emitting any
|
||||
DW_TAG_inlined_subroutine DIE as a descendent
|
||||
of an abstract function instance. So in that case, we should
|
||||
not call gen_inlined_subroutine_die.
|
||||
|
||||
Later though, when cgraph asks dwarf2out to emit info
|
||||
for the concrete instance of the function decl into which
|
||||
the concrete instance of STMT got inlined, the later will lead
|
||||
to the generation of a DW_TAG_inlined_subroutine DIE. */
|
||||
if (! BLOCK_ABSTRACT (stmt))
|
||||
gen_inlined_subroutine_die (stmt, context_die, depth);
|
||||
}
|
||||
else
|
||||
gen_lexical_block_die (stmt, context_die, depth);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2009-08-16 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
* gcc/testsuite/gcc.dg/debug/20020224-1.c: Adjust the comment.
|
||||
Make sure to trigger inlining optimizations.
|
||||
* gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c: New test.
|
||||
|
||||
2009-08-14 Janus Weil <janus@gcc.gnu.org>
|
||||
|
||||
PR fortran/41070
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
/* { dg-options "-g3 -O" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Here's the deal: f3 is not inlined because it's too big, but f2 and
|
||||
f1 are inlined into it. We used to fail to emit debugging info for
|
||||
t1, because it was moved inside the (inlined) block of f1, marked
|
||||
as abstract, then we'd crash. */
|
||||
/* Here's the deal: f4 is inlined into main, f3 is inlined into f4, f2 is
|
||||
inlined into f1. The DIE of main should contain DW_TAG_inlined_subroutines
|
||||
children for f4, f3, f2 and f1. Also, there should be a DIE representing
|
||||
and out of line instance of f4, aside the DIE representing its abstract
|
||||
instance.
|
||||
We used to fail to emit debugging info for t1, because it was moved
|
||||
inside the (inlined) block of f1, marked as abstract, then we'd crash. */
|
||||
|
||||
#define UNUSED __attribute__((unused))
|
||||
#define EXT __extension__
|
||||
|
@ -58,3 +62,10 @@ f4 (void)
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int foo = 1;
|
||||
f4 ();
|
||||
}
|
||||
|
|
70
gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
Normal file
70
gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* Contributed by Dodji Seketeli <dodji@redhat.com>
|
||||
Origin: PR debug/37801
|
||||
|
||||
Abstract instances (DW_TAG_subroutines having the DW_AT_inline attribute)
|
||||
of second and first were having a DW_TAG_lexical_block DIE wrongly
|
||||
representing the inlined calls to third (in second) and to
|
||||
second (in first). At the same time, main didn't have children
|
||||
DW_TAG_inlined_subroutine DIEs representing the inlined calls to
|
||||
first, second and third.
|
||||
|
||||
The ideal goal here is to test that we have no superfluous
|
||||
DW_TAG_lexical_block DIE anymore, that abstract instances DIEs have
|
||||
no descendant DIE with a DW_AT_abstract_origin attribute, and that main has
|
||||
properly nested DW_TAG_inlined_subroutine DIEs for third, second and first.
|
||||
*/
|
||||
|
||||
/* { dg-options "-O -g3" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* There are 6 inlined subroutines:
|
||||
- One for each subroutine inlined into main, that's 3.
|
||||
- One for earch subroutine inline into the out of line instances
|
||||
of third, second and first. */
|
||||
/* { dg-final { scan-assembler-times "\\(DIE \\(.*?\\) DW_TAG_inlined_subroutine" 6 } } */
|
||||
|
||||
/* Likewise we should have 6 DW_TAG_lexical_block DIEs:
|
||||
- One for each subroutine inlined into main, so that's 3.
|
||||
- One for each subroutine inlined in the out of line instances
|
||||
of third, second and first, that's 3.
|
||||
*/
|
||||
/* { dg-final { scan-assembler-times "\\(DIE \\(.*?\\) DW_TAG_lexical_block" 6 } } */
|
||||
|
||||
|
||||
/* There are 3 DW_AT_inline attributes: one per abstract inline instance.
|
||||
The value of the attribute must be 0x3, meaning the function was
|
||||
actually inlined. */
|
||||
/* { dg-final { scan-assembler-times "byte.*?0x3.*? DW_AT_inline" 3 } } */
|
||||
|
||||
|
||||
inline void
|
||||
third (int arg3)
|
||||
{
|
||||
int var3 = arg3;
|
||||
int* a = 0;
|
||||
a[0] = var3;
|
||||
}
|
||||
|
||||
inline void
|
||||
second (int arg2)
|
||||
{
|
||||
int var2 = arg2;
|
||||
third (var2+1);
|
||||
}
|
||||
|
||||
inline void
|
||||
first (int arg1)
|
||||
{
|
||||
int var1 = arg1;
|
||||
second (var1+1);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int some_int = 1;
|
||||
first (some_int);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue