diff mbox

Fix DWARF so types with subprogram definitions don't get moved to type unit (issue4433068)

Message ID 20110425212703.D9F94481B2@thebrac.mtv.corp.google.com
State New
Headers show

Commit Message

Cary Coutant April 25, 2011, 9:27 p.m. UTC
In GCC 4.4.3, I found a case where a defining declaration of a subprogram
was included within the DIE structure for the containing class declaration,
and the class was moved into a DWARF-4 type unit, causing a later ICE in
output_pubnames. That case doesn't cause a problem in 4.5 and later, as
the subprogram DIE is generated at the top level with a DW_AT_specification
pointing to the declaration DIE inside the class. Nevertheless, I think
it's a good safety measure to ensure that if a class does contain a
subprogram definition, it shouldn't be moved to a type unit -- such a
type would never be identical across different compilation units.

This patch checks for classes that contain defining declarations of
subprograms, and does not move such classes into a comdat type unit.

OK for trunk? I don't think it's critical to 4.6, but if it's acceptable
for 4.6, that would be nice, too.

-cary


Tested:
  Bootstrapped on x86_64.

ChangeLog:

2011-04-25  Cary Coutant  <ccoutant@google.com>

	* gcc/dwarf2out.c (contains_subprogram_definition): New function.
	(should_move_die_to_comdat): Call it.


--
This patch is available for review at http://codereview.appspot.com/4433068
diff mbox

Patch

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index f3c4c09..8262cc7 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10018,6 +10018,20 @@  is_nested_in_subprogram (dw_die_ref die)
   return local_scope_p (decl);
 }
 
+/* Return non-zero if this DIE contains a defining declaration of a
+   subprogram.  */
+
+static int
+contains_subprogram_definition (dw_die_ref die)
+{
+  dw_die_ref c;
+
+  if (die->die_tag == DW_TAG_subprogram && ! is_declaration_die (die))
+    return 1;
+  FOR_EACH_CHILD (die, c, if (contains_subprogram_definition(c)) return 1);
+  return 0;
+}
+
 /* Return non-zero if this is a type DIE that should be moved to a
    COMDAT .debug_types section.  */
 
@@ -10034,7 +10048,8 @@  should_move_die_to_comdat (dw_die_ref die)
 	 subprogram.  */
       if (is_declaration_die (die)
           || get_AT (die, DW_AT_abstract_origin)
-          || is_nested_in_subprogram (die))
+          || is_nested_in_subprogram (die)
+          || contains_subprogram_definition (die))
         return 0;
       return 1;
     case DW_TAG_array_type: