re PR debug/37801 (DWARF output for inlined functions doesn't always use DW_TAG_inlin...
authorRichard Biener <rguenther@suse.de>
Thu, 27 Sep 2018 14:10:45 +0000 (14:10 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 27 Sep 2018 14:10:45 +0000 (14:10 +0000)
2018-09-27  Richard Biener  <rguenther@suse.de>

PR debug/37801
PR debug/87440
* dwarf2out.c (set_block_origin_self): Do not mark outermost
block as we do not output that.
(gen_inlined_subroutine_die): Elide the originally outermost
block, matching what we do for concrete instances.
(decls_for_scope): Add parameter specifying whether to recurse
to subblocks.

* gcc.dg/debug/dwarf2/inline2.c: Adjust.
* gcc.dg/debug/dwarf2/inline4.c: New testcase.

From-SVN: r264667

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

index 4606d9d108b7fc411ea4361ad22fb9f7c5259696..4255d268398933a964c428b0d7195d71195d9c2e 100644 (file)
@@ -1,3 +1,14 @@
+2018-09-27  Richard Biener  <rguenther@suse.de>
+
+       PR debug/37801
+       PR debug/87440
+       * dwarf2out.c (set_block_origin_self): Do not mark outermost
+       block as we do not output that.
+       (gen_inlined_subroutine_die): Elide the originally outermost
+       block, matching what we do for concrete instances.
+       (decls_for_scope): Add parameter specifying whether to recurse
+       to subblocks.
+
 2018-09-27  Andrew Stubbs  <ams@codesourcery.com>
             Tom de Vries  <tom@codesourcery.com>
 
index b0c5c4f2512ce79ccbc779e719d3270e74e57095..a63a645e84ad50c9ea69656af8bdece1f475ec42 100644 (file)
@@ -3867,7 +3867,7 @@ static void gen_subroutine_type_die (tree, dw_die_ref);
 static void gen_typedef_die (tree, dw_die_ref);
 static void gen_type_die (tree, dw_die_ref);
 static void gen_block_die (tree, dw_die_ref);
-static void decls_for_scope (tree, dw_die_ref);
+static void decls_for_scope (tree, dw_die_ref, bool = true);
 static bool is_naming_typedef_decl (const_tree);
 static inline dw_die_ref get_context_die (tree);
 static void gen_namespace_die (tree, dw_die_ref);
@@ -24147,7 +24147,23 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die)
         add_high_low_attributes (stmt, subr_die);
       add_call_src_coords_attributes (stmt, subr_die);
 
-      decls_for_scope (stmt, subr_die);
+      /* The inliner creates an extra BLOCK for the parameter setup,
+         we want to merge that with the actual outermost BLOCK of the
+        inlined function to avoid duplicate locals in consumers.
+        Do that by doing the recursion to subblocks on the single subblock
+        of STMT.  */
+      bool unwrap_one = false;
+      if (BLOCK_SUBBLOCKS (stmt) && !BLOCK_CHAIN (BLOCK_SUBBLOCKS (stmt)))
+       {
+         tree origin = block_ultimate_origin (BLOCK_SUBBLOCKS (stmt));
+         if (origin
+             && TREE_CODE (origin) == BLOCK
+             && BLOCK_SUPERCONTEXT (origin) == decl)
+           unwrap_one = true;
+       }
+      decls_for_scope (stmt, subr_die, !unwrap_one);
+      if (unwrap_one)
+       decls_for_scope (BLOCK_SUBBLOCKS (stmt), subr_die);
     }
 }
 
@@ -25775,7 +25791,7 @@ process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
    all of its sub-blocks.  */
 
 static void
-decls_for_scope (tree stmt, dw_die_ref context_die)
+decls_for_scope (tree stmt, dw_die_ref context_die, bool recurse)
 {
   tree decl;
   unsigned int i;
@@ -25818,10 +25834,11 @@ decls_for_scope (tree stmt, dw_die_ref context_die)
 
   /* Output the DIEs to represent all sub-blocks (and the items declared
      therein) of this block.  */
-  for (subblocks = BLOCK_SUBBLOCKS (stmt);
-       subblocks != NULL;
-       subblocks = BLOCK_CHAIN (subblocks))
-    gen_block_die (subblocks, context_die);
+  if (recurse)
+    for (subblocks = BLOCK_SUBBLOCKS (stmt);
+        subblocks != NULL;
+        subblocks = BLOCK_CHAIN (subblocks))
+      gen_block_die (subblocks, context_die);
 }
 
 /* Is this a typedef we can avoid emitting?  */
index d723ef42ee47aeb08cdfff5d21d094a3ed8aa445..712e2be38d56a1e510dda665105f3cd867e540c3 100644 (file)
@@ -1,3 +1,10 @@
+2018-09-27  Richard Biener  <rguenther@suse.de>
+
+       PR debug/37801
+       PR debug/87440
+       * gcc.dg/debug/dwarf2/inline2.c: Adjust.
+       * gcc.dg/debug/dwarf2/inline4.c: New testcase.
+
 2018-09-27  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/67544
index b2ae111317608cfc292ae91fc5915150f03559e4..7e019a6c06a0e5c73fe40288fa6e5dbf62257e4d 100644 (file)
      of third, second and first.  */
 /* { dg-final { scan-assembler-times "\\(DIE \\(\[^\n\]*\\) 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 \\(\[^\n\]*\\) DW_TAG_lexical_block" 6 } } */
+/* We should have no DW_TAG_lexical_block DIEs, all inline instances
+   should have the first subblock elided to match the abstract instance
+   layout.  */
+/* { dg-final { scan-assembler-times "\\(DIE \\(\[^\n\]*\\) DW_TAG_lexical_block" 0 } } */
 
 
 /* There are 3 DW_AT_inline attributes: one per abstract inline instance.
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline4.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline4.c
new file mode 100644 (file)
index 0000000..2faef6e
--- /dev/null
@@ -0,0 +1,17 @@
+/* Verify that the inline instance has no extra DW_TAG_lexical_block between
+   the DW_TAG_inlined_subroutine and the DW_TAG_variable for the local.  */
+/* { dg-options "-O -gdwarf -dA" } */
+/* { dg-do compile } */
+/* { dg-final { scan-assembler "DW_TAG_inlined_subroutine\[^\\(\]*\\(\[^\\)\]*\\)\[^\\(\]*\\(DIE \\(0x\[0-9a-f\]*\\) DW_TAG_formal_parameter\[^\\(\]*\\(DIE \\(0x\[0-9a-f\]*\\) DW_TAG_variable" } } */
+/* { dg-final { scan-assembler-times "DW_TAG_inlined_subroutine" 2 } } */
+
+static int foo (int i)
+{
+  volatile int j = i + 3;
+  return j - 2;
+}
+int main()
+{
+  volatile int z = foo (-1);
+  return z;
+}