This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Ada] Fix ICE on initialization with discriminated aggregate
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 30 Aug 2011 18:17:18 +0200
- Subject: [Ada] Fix ICE on initialization with discriminated aggregate
The compiler aborts on the initialization of an object with an aggregate, if
its nominal subtype is a discriminated record type with a variant part for
which the variants all have the same size and one of the variants contains a
component whose type is tagged or controlled.
Tested on x86_64-suse-linux, applied on the mainline.
2011-08-30 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Do not convert
the expression to the nominal type if the latter is a record type with
a variant part and the type of the former is a record type without one.
2011-08-30 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/aggr3.ads: New test.
* gnat.dg/specs/aggr3_pkg.ads: New helper.
--
Eric Botcazou
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c (revision 178287)
+++ gcc-interface/decl.c (working copy)
@@ -1124,13 +1124,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
is a padded record whose field is of self-referential size. In
the former case, converting will generate unnecessary evaluations
of the CONSTRUCTOR to compute the size and in the latter case, we
- want to only copy the actual data. */
+ want to only copy the actual data. Also don't convert to a record
+ type with a variant part from a record type without one, to keep
+ the object simpler. */
if (gnu_expr
&& TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE
&& !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type))
&& !(TYPE_IS_PADDING_P (gnu_type)
&& CONTAINS_PLACEHOLDER_P
- (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (gnu_type))))))
+ (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (gnu_type)))))
+ && !(TREE_CODE (gnu_type) == RECORD_TYPE
+ && TREE_CODE (TREE_TYPE (gnu_expr)) == RECORD_TYPE
+ && get_variant_part (gnu_type) != NULL_TREE
+ && get_variant_part (TREE_TYPE (gnu_expr)) == NULL_TREE))
gnu_expr = convert (gnu_type, gnu_expr);
/* If this is a pointer that doesn't have an initializing expression,
@@ -1350,13 +1356,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
is a padded record whose field is of self-referential size. In
the former case, converting will generate unnecessary evaluations
of the CONSTRUCTOR to compute the size and in the latter case, we
- want to only copy the actual data. */
+ want to only copy the actual data. Also don't convert to a record
+ type with a variant part from a record type without one, to keep
+ the object simpler. */
if (gnu_expr
&& TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE
&& !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type))
&& !(TYPE_IS_PADDING_P (gnu_type)
&& CONTAINS_PLACEHOLDER_P
- (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (gnu_type))))))
+ (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (gnu_type)))))
+ && !(TREE_CODE (gnu_type) == RECORD_TYPE
+ && TREE_CODE (TREE_TYPE (gnu_expr)) == RECORD_TYPE
+ && get_variant_part (gnu_type) != NULL_TREE
+ && get_variant_part (TREE_TYPE (gnu_expr)) == NULL_TREE))
gnu_expr = convert (gnu_type, gnu_expr);
/* If this name is external or there was a name specified, use it,
-- { dg-do compile }
with Aggr3_Pkg; use Aggr3_Pkg;
package Aggr3 is
type Enum is (One);
type R (D : Enum := One) is
record
case D is
when One => The_T : T;
end case;
end record;
My_R : R := (D => One, The_T => My_T);
end Aggr3;
package Aggr3_Pkg is
type Root is abstract tagged null record;
type T is new Root with null record;
My_T : T;
end Aggr3_Pkg;