This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Ada] Fix ICE on discriminated record with representation clause
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 19 Jul 2012 17:40:22 +0200
- Subject: [Ada] Fix ICE on discriminated record with representation clause
This is a regression present on the mainline and 4.7 branch. When a
discriminated record type with a variant part has a partial representation
clause, the compiler may drop some fields when it is laying out subtypes of
this record type.
Tested on x86_64-suse-linux, applied on the mainline and 4.7 branch.
2012-07-19 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: Do not
look up the REP part of the base type in advance. Deal with that of
the variant types.
(get_rep_part): Be prepared for record types with fields.
2012-07-19 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/discr38.adb: New test.
--
Eric Botcazou
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c (revision 189607)
+++ gcc-interface/decl.c (working copy)
@@ -3287,9 +3287,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
else
gnu_unpad_base_type = gnu_base_type;
- /* Look for a REP part in the base type. */
- gnu_rep_part = get_rep_part (gnu_unpad_base_type);
-
/* Look for a variant part in the base type. */
gnu_variant_part = get_variant_part (gnu_unpad_base_type);
@@ -3415,7 +3412,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
and put the field either in the new type if there is a
selected variant or in one of the new variants. */
if (gnu_context == gnu_unpad_base_type
- || (gnu_rep_part
+ || ((gnu_rep_part = get_rep_part (gnu_unpad_base_type))
&& gnu_context == TREE_TYPE (gnu_rep_part)))
gnu_cont_type = gnu_type;
else
@@ -3425,7 +3422,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
t = NULL_TREE;
FOR_EACH_VEC_ELT (variant_desc, gnu_variant_list, i, v)
- if (v->type == gnu_context)
+ if (gnu_context == v->type
+ || ((gnu_rep_part = get_rep_part (v->type))
+ && gnu_context == TREE_TYPE (gnu_rep_part)))
{
t = v->type;
break;
@@ -8172,7 +8171,8 @@ get_rep_part (tree record_type)
/* The REP part is the first field, internal, another record, and its name
starts with an 'R'. */
- if (DECL_INTERNAL_P (field)
+ if (field
+ && DECL_INTERNAL_P (field)
&& TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
&& IDENTIFIER_POINTER (DECL_NAME (field)) [0] == 'R')
return field;
-- { dg-do compile }
procedure Discr38 is
type Enum is (OK,
NOT_CONNECTED,
DISCONNECTED,
REQUEST_Q_EMPTY,
SERVER_UNAVAILABLE,
BUFFER_TOO_SMALL,
NO_FREE_SLOT,
RAISE_EXCEPTION,
REQUEST_CANCELLED,
REQUEST_IN_PROGRESS,
SERVER_BUSY,
BLOCK_ACKNOWLEDGE);
type R (Status : Enum := OK) is record
Status_Block : Integer;
case Status is
when RAISE_EXCEPTION =>
I : Integer;
when OK =>
Length : Natural;
Data : Integer;
when others =>
null;
end case;
end record;
for R use record
Status at 0 range 0 .. 7;
Status_Block at 4 range 0 .. 31;
Length at 8 range 0 .. 31;
end record;
Nil : constant R := (OK, 1, 0, 1);
begin
null;
end;