This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix dwarf2out ICE when cp_emit_debug_info_for_using a FIELD_DECL from TYPE_DECL_SUPPRESS_DEBUG aggregate (PR c++/19406)


Hi!

If GCC decides to suppress debug info for a class, but one of its field
is referenced through using, GCC ICEs, as that FIELD_DECL has no
die.  The following patch handles this by creating the die for the field.
Is this ok or is that a wrong approach?

2005-01-18  Jakub Jelinek  <jakub@redhat.com>

	PR c++/19406
	* dwarf2out.c (gen_type_die_for_member): Handle FIELD_DECL.
	(dwarf2out_imported_module_or_decl): Use gen_type_die_for_member
	for FIELD_DECLs.

	* g++.dg/debug/using1.C: New test.

--- gcc/dwarf2out.c.jj	2005-01-07 09:47:52.000000000 +0100
+++ gcc/dwarf2out.c	2005-01-18 13:36:43.446571862 +0100
@@ -11103,12 +11103,26 @@ gen_type_die_for_member (tree type, tree
       && ! lookup_decl_die (member))
     {
       gcc_assert (!decl_ultimate_origin (member));
+      dw_die_ref type_die;
 
       push_decl_scope (type);
+      type_die = lookup_type_die (type);
       if (TREE_CODE (member) == FUNCTION_DECL)
-	gen_subprogram_die (member, lookup_type_die (type));
+	gen_subprogram_die (member, type_die);
+      else if (TREE_CODE (member) == FIELD_DECL)
+	{
+	  /* Ignore the nameless fields that are used to skip bits but handle
+	     C++ anonymous unions and structs.  */
+	  if (DECL_NAME (member) != NULL_TREE
+	      || TREE_CODE (TREE_TYPE (member)) == UNION_TYPE
+	      || TREE_CODE (TREE_TYPE (member)) == RECORD_TYPE)
+	    {
+	      gen_type_die (member_declared_type (member), type_die);
+	      gen_field_die (member, type_die);
+	    }
+	}
       else
-	gen_variable_die (member, lookup_type_die (type));
+	gen_variable_die (member, type_die);
 
       pop_decl_scope ();
     }
@@ -12794,7 +12808,29 @@ dwarf2out_imported_module_or_decl (tree 
   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
     at_import_die = force_type_die (TREE_TYPE (decl));
   else
-    at_import_die = force_decl_die (decl);
+    {
+      at_import_die = lookup_decl_die (decl);
+      if (!at_import_die)
+	{
+	  /* If we're trying to avoid duplicate debug info, we may not have
+	     emitted the member decl for this field.  Emit it now.  */
+	  if (TREE_CODE (decl) == FIELD_DECL)
+	    {
+	      tree type = DECL_CONTEXT (decl);
+	      dw_die_ref type_context_die;
+
+	      if (TYPE_CONTEXT (type))
+		if (TYPE_P (TYPE_CONTEXT (type)))
+		  type_context_die = force_type_die (TYPE_CONTEXT (type));
+	      else
+		type_context_die = force_decl_die (TYPE_CONTEXT (type));
+	      else
+		type_context_die = comp_unit_die;
+	      gen_type_die_for_member (type, decl, type_context_die);
+	    }
+	  at_import_die = force_decl_die (decl);
+	}
+    }
 
   /* OK, now we have DIEs for decl as well as scope. Emit imported die.  */
   if (TREE_CODE (decl) == NAMESPACE_DECL)
--- gcc/testsuite/g++.dg/debug/using1.C.jj	2005-01-18 13:59:13.656563308 +0100
+++ gcc/testsuite/g++.dg/debug/using1.C	2005-01-18 13:59:45.625880303 +0100
@@ -0,0 +1,15 @@
+// PR c++/19406
+// { dg-do compile }
+
+struct A
+{
+  virtual int foo();
+  double d;
+};
+
+struct B : public A
+{
+  A::d;
+};
+
+B b;

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]