OSDN Git Service

Fix for PR debug/37801
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 16 Aug 2009 09:02:25 +0000 (09:02 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 16 Aug 2009 09:02:25 +0000 (09:02 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150796 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/debug/20020224-1.c
gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c [new file with mode: 0644]

index 1f89aea..f0a3061 100644 (file)
@@ -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.
index af97bb0..2ee1df8 100644 (file)
@@ -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);
     }
index 44329fb..6c7bb39 100644 (file)
@@ -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
index c61a17a..968b565 100644 (file)
@@ -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 (file)
index 0000000..6ef01df
--- /dev/null
@@ -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;
+}
+
+