This is the mail archive of the 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]

[Ada] Fix internal type consistency problem

This patch fixes an old internal type consistency problem pertaining to record 
subtypes constraining discriminants of their base type.  If a field is of a 
nominal discriminated record type with default discriminant and is unrelated 
to the discriminants being constrained, the base type uses a padded type for 
the field but the subtype still uses the nominal discriminated record type, 
leading to wrong debug info; both should use the padded type.

Tested on i586-suse-linux, applied on the mainline.

2009-05-20  Eric Botcazou  <>

	* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: When
	discriminants affect the shape of the subtype, retrieve the GCC type
	directly from the original field if the GNAT types for the field and
	the original field are the same.

Eric Botcazou
Index: gcc-interface/decl.c
--- gcc-interface/decl.c	(revision 147612)
+++ gcc-interface/decl.c	(working copy)
@@ -3124,21 +3124,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 			|| !Is_Tagged_Type (gnat_base_type)))
 		    tree gnu_old_field
-		      = gnat_to_gnu_field_decl (Original_Record_Component
-						(gnat_field));
+		      = gnat_to_gnu_field_decl
+			(Original_Record_Component (gnat_field));
 		    tree gnu_offset
-		      = TREE_VALUE (purpose_member (gnu_old_field,
-						    gnu_pos_list));
+		      = TREE_VALUE
+			(purpose_member (gnu_old_field, gnu_pos_list));
 		    tree gnu_pos = TREE_PURPOSE (gnu_offset);
 		    tree gnu_bitpos = TREE_VALUE (TREE_VALUE (gnu_offset));
-		    tree gnu_field_type
-		      = gnat_to_gnu_type (Etype (gnat_field));
-		    tree gnu_size = TYPE_SIZE (gnu_field_type);
-		    tree gnu_new_pos = NULL_TREE;
+		    tree gnu_field, gnu_field_type, gnu_size, gnu_new_pos;
 		    unsigned int offset_align
-		      = tree_low_cst (TREE_PURPOSE (TREE_VALUE (gnu_offset)),
-				      1);
-		    tree gnu_field;
+		      = tree_low_cst
+			(TREE_PURPOSE (TREE_VALUE (gnu_offset)), 1);
+		    /* If the type is the same, retrieve the GCC type from the
+		       old field to take into account possible adjustments.  */
+		    if (Etype (gnat_field)
+			== Etype (Original_Record_Component (gnat_field)))
+		      gnu_field_type = TREE_TYPE (gnu_old_field);
+		    else
+		      gnu_field_type = gnat_to_gnu_type (Etype (gnat_field));
+		    gnu_size = TYPE_SIZE (gnu_field_type);
 		    /* If there was a component clause, the field types must be
 		       the same for the type and subtype, so copy the data from
@@ -3197,6 +3203,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 						 TYPE_SIZE (gnu_type)))
+		    else
+		      gnu_new_pos = NULL_TREE;
 		      = create_field_decl

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