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]

Fix PR ada/28591


The problem is an ICE on a sanity check when generating debug info for an
unchecked union, a regression present on the mainline.  The DWARF-2 back-end 
aborts because it detects that it is emitting debug info for the same field 
inside two differents contexts, a record type and a union type.

The problematic field is the one reused in components_to_record in case it
is the unique field of the record type representing a variant part of an
unchecked union.  The fix is not to emit debug info for the record type
before knowing whether it will actually be used.

Bootstrapped/regtested on i586-suse-linux, applied to the mainline.


2006-09-13  Eric Botcazou  <ebotcazou@adacore.com>

	PR ada/28591
	* decl.c (components_to_record): Defer emitting debug info for the
	record type associated with the variant until after we are sure to
	actually use it. 


2006-09-13  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/specs/unchecked_union.ads: New test.


-- 
Eric Botcazou
Index: decl.c
===================================================================
RCS file: /gnat.dev/cvs/Dev/gnat/decl.c,v
retrieving revision 1.63.2.155
retrieving revision 1.63.2.156
diff -u -p -r1.63.2.155 -r1.63.2.156
--- decl.c	7 Apr 2006 16:00:53 -0000	1.63.2.155
+++ decl.c	11 Apr 2006 19:36:20 -0000	1.63.2.156
@@ -5720,10 +5720,12 @@ components_to_record (tree gnu_record_ty
 		= TYPE_SIZE_UNIT (gnu_record_type);
 	    }
 
+	  /* Create the record for the variant.  Note that we defer emitting
+	     debug info for it until after we are sure to actually use it.  */
 	  components_to_record (gnu_variant_type, Component_List (variant),
 				NULL_TREE, packed, definition,
 				&gnu_our_rep_list, !all_rep_and_size, all_rep,
-				false, unchecked_union);
+				true, unchecked_union);
 
 	  gnu_qual = choices_to_gnu (gnu_discriminant,
 				     Discrete_Choices (variant));
@@ -5737,6 +5739,13 @@ components_to_record (tree gnu_record_ty
 	    gnu_field = TYPE_FIELDS (gnu_variant_type);
 	  else
 	    {
+	      /* Emit debug info for the record.  We used to throw away
+		 empty records but we no longer do that because we need
+		 them to generate complete debug info for the variant;
+		 otherwise, the union type definition will be lacking
+		 the fields associated with these empty variants.  */
+	      write_record_type_debug_info (gnu_variant_type);
+
 	      gnu_field = create_field_decl (gnu_inner_name, gnu_variant_type,
 					     gnu_union_type, 0,
 					     (all_rep_and_size
@@ -5756,12 +5765,6 @@ components_to_record (tree gnu_record_ty
 	  gnu_variant_list = gnu_field;
 	}
 
-      /* We used to delete the empty variants from the end. However,
-         we no longer do that because we need them to generate complete
-         debugging information for the variant record.  Otherwise,
-         the union type definition will be missing the fields associated
-         to these empty variants.  */
-
       /* Only make the QUAL_UNION_TYPE if there are any non-empty variants.  */
       if (gnu_variant_list)
 	{
-- { dg-do compile }
-- { dg-options "-g" }

with Interfaces; use Interfaces;

package Types is
   type Mode_Type is (Mode_B2);

   type Value_Union (Mode : Mode_Type := Mode_B2) is record
      case Mode is
         when Mode_B2 =>
            B2 : Integer_32;
      end case;
   end record;
   pragma Unchecked_Union (Value_Union);

end Types;

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