diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f89aea5abb..f0a306195e1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-08-16 Dodji Seketeli + + * 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 * graphite-poly.c (print_pbb): Print PBB index. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index af97bb0fee7..2ee1df80ca0 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 44329fb3c53..6c7bb39f12a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-08-16 Dodji Seketeli + + * 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 PR fortran/41070 diff --git a/gcc/testsuite/gcc.dg/debug/20020224-1.c b/gcc/testsuite/gcc.dg/debug/20020224-1.c index c61a17aed10..968b5655b39 100644 --- a/gcc/testsuite/gcc.dg/debug/20020224-1.c +++ b/gcc/testsuite/gcc.dg/debug/20020224-1.c @@ -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 (); +} diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c new file mode 100644 index 00000000000..6ef01dff48f --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c @@ -0,0 +1,70 @@ +/* Contributed by Dodji Seketeli + 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; +} + +