+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.
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
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. */
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);
}
+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
+/* { 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__
return;
}
+
+int
+main ()
+{
+ int foo = 1;
+ f4 ();
+}
--- /dev/null
+/* 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;
+}
+
+