Hi,

This patch fixes a crash seen when gdb was debugging D programs.

Calling `rest_of_type_compilation' as the D types were built meant that
debug info was being emitted before all forward references were
resolved, resulting in DW_AT_name's to be missing.

Instead, defer outputting type debug information until all modules have
been parsed and generated in `d_finish_compilation'.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32, and
committed to mainline.

Regards,
Iain.

---
        PR d/118309

gcc/d/ChangeLog:

        * modules.cc: Include debug.h
        (d_finish_compilation): Call debug_hooks->type_decl on all TYPE_DECLs.
        * types.cc: Remove toplev.h include.
        (finish_aggregate_type): Don't call rest_of_type_compilation or
        rest_of_decl_compilation on type.
        (TypeVisitor::visit (TypeEnum *)): Likewise.

gcc/testsuite/ChangeLog:

        * gdc.dg/debug/dwarf2/pr118309.d: New test.
---
 gcc/d/modules.cc                             |  9 +++++
 gcc/d/types.cc                               | 15 ++------
 gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d | 36 ++++++++++++++++++++
 3 files changed, 47 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d

diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index 813d94bc5c4..14e4a485043 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "function.h"
 #include "cgraph.h"
 #include "stor-layout.h"
+#include "debug.h"
 #include "toplev.h"
 #include "target.h"
 #include "common/common-target.h"
@@ -927,6 +928,14 @@ d_finish_compilation (tree *vec, int len)
   /* Complete all generated thunks.  */
   symtab->process_same_body_aliases ();
 
+  /* Output debug information for all type declarations in this unit.  */
+  for (int i = 0; i < len; i++)
+    {
+      tree decl = vec[i];
+      if (TREE_CODE (decl) == TYPE_DECL)
+       debug_hooks->type_decl (decl, false);
+    }
+
   /* Process all file scopes in this compilation, and the external_scope,
      through wrapup_global_declarations.  */
   for (int i = 0; i < len; i++)
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index ea62bc9d05e..e43fa88a5d4 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -33,7 +33,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "tm.h"
 #include "function.h"
-#include "toplev.h"
 #include "target.h"
 #include "stringpool.h"
 #include "stor-layout.h"
@@ -709,13 +708,8 @@ finish_aggregate_type (unsigned structsize, unsigned 
alignsize, tree type)
       TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (type);
     }
 
-  /* Finish debugging output for this type.  */
-  rest_of_type_compilation (type, TYPE_FILE_SCOPE_P (type));
+  /* Complete any other forward-referenced fields of this aggregate type.  */
   finish_incomplete_fields (type);
-
-  /* Finish processing of TYPE_DECL.  */
-  rest_of_decl_compilation (TYPE_NAME (type),
-                           DECL_FILE_SCOPE_P (TYPE_NAME (type)), 0);
 }
 
 /* Returns true if the class or struct type TYPE has already been layed out by
@@ -1185,13 +1179,8 @@ public:
 
        layout_type (t->ctype);
 
-       /* Finish debugging output for this type.  */
-       rest_of_type_compilation (t->ctype, TYPE_FILE_SCOPE_P (t->ctype));
+       /* Complete forward-referenced fields of this enum type.  */
        finish_incomplete_fields (t->ctype);
-
-       /* Finish processing of TYPE_DECL.  */
-       rest_of_decl_compilation (TYPE_NAME (t->ctype),
-                                 DECL_FILE_SCOPE_P (TYPE_NAME (t->ctype)), 0);
       }
   }
 
diff --git a/gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d 
b/gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d
new file mode 100644
index 00000000000..50e42164eef
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/debug/dwarf2/pr118309.d
@@ -0,0 +1,36 @@
+// { dg-do compile }
+// { dg-options "-fno-druntime -gdwarf-4 -dA -fno-merge-debug-strings" }
+// { dg-final { scan-assembler-times "DIE\[^\n\r\]*DW_TAG_enumeration_type" 1 
} }
+// { dg-final { scan-assembler-times " DW_AT_enum_class" 1 } }
+// { dg-final { scan-assembler-times "\"E..\"\[^\n\]*DW_AT_name" 1 } }
+// { dg-final { scan-assembler-times "\"E1..\"\[^\n\]*DW_AT_name" 1 } }
+// { dg-final { scan-assembler-times "\"C1..\"\[^\n\]*DW_AT_name" 1 } }
+// { dg-final { scan-assembler-times "\"C2..\"\[^\n\]*DW_AT_name" 1 } }
+// { dg-final { scan-assembler-times "\"C3..\"\[^\n\]*DW_AT_name" 1 } }
+// { dg-final { scan-assembler-times "\"C4..\"\[^\n\]*DW_AT_name" 1 } }
+// { dg-final { scan-assembler-times "\"S1..\"\[^\n\]*DW_AT_name" 1 } }
+
+module expression;
+extern (C++):
+class C1
+{
+    bool bfn() { return true; }
+}
+class C2 : C1
+{
+    C4 cfn() { return null; }
+}
+class C3 : C2
+{
+    S1.E s;
+}
+class C4 : C3
+{
+    S1 s;
+}
+struct S1
+{
+    enum E : ubyte { E1 }
+    E e;
+    C3 c;
+}
-- 
2.43.0

Reply via email to