This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Ada] Fix internal type consistency problem
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 20 May 2009 10:34:55 +0200
- Subject: [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 <ebotcazou@adacore.com>
* 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)))
continue;
}
+ else
+ gnu_new_pos = NULL_TREE;
gnu_field
= create_field_decl