[Ada] Fix internal error on unchecked union with component clauses (2)
The issue arises when the unchecked union contains both a fixed part and a variant part, and is subject to a full representation clause covering all the components in all the variants, when the component clauses do not align the variant boundaries with byte boundaries consistently. gcc/ada/ * gcc-interface/decl.cc (components_to_record): Use NULL recursively as P_GNU_REP_LIST for the innermost variant level in the unchecked union case with a fixed part.
This commit is contained in:
parent
b64c4968c7
commit
db6734819f
@ -7981,6 +7981,7 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
|
|||||||
tree gnu_union_type;
|
tree gnu_union_type;
|
||||||
tree this_first_free_pos, gnu_variant_list = NULL_TREE;
|
tree this_first_free_pos, gnu_variant_list = NULL_TREE;
|
||||||
bool union_field_needs_strict_alignment = false;
|
bool union_field_needs_strict_alignment = false;
|
||||||
|
bool innermost_variant_level = true;
|
||||||
auto_vec <vinfo_t, 16> variant_types;
|
auto_vec <vinfo_t, 16> variant_types;
|
||||||
vinfo_t *gnu_variant;
|
vinfo_t *gnu_variant;
|
||||||
unsigned int variants_align = 0;
|
unsigned int variants_align = 0;
|
||||||
@ -8026,6 +8027,19 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For an unchecked union with a fixed part, we need to compute whether
|
||||||
|
we are at the innermost level of the variant part. */
|
||||||
|
if (unchecked_union && gnu_field_list)
|
||||||
|
for (variant = First_Non_Pragma (Variants (gnat_variant_part));
|
||||||
|
Present (variant);
|
||||||
|
variant = Next_Non_Pragma (variant))
|
||||||
|
if (Present (Component_List (variant))
|
||||||
|
&& Present (Variant_Part (Component_List (variant))))
|
||||||
|
{
|
||||||
|
innermost_variant_level = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* We build the variants in two passes. The bulk of the work is done in
|
/* We build the variants in two passes. The bulk of the work is done in
|
||||||
the first pass, that is to say translating the GNAT nodes, building
|
the first pass, that is to say translating the GNAT nodes, building
|
||||||
the container types and computing the associated properties. However
|
the container types and computing the associated properties. However
|
||||||
@ -8066,11 +8080,12 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
|
|||||||
|
|
||||||
/* Add the fields into the record type for the variant but note that
|
/* Add the fields into the record type for the variant but note that
|
||||||
we aren't sure to really use it at this point, see below. In the
|
we aren't sure to really use it at this point, see below. In the
|
||||||
case of an unchecked union, we force the fields with a rep clause
|
case of an unchecked union with a fixed part, we force the fields
|
||||||
present in a nested variant to be moved to the outermost variant,
|
with a rep clause present in the innermost variant to be moved to
|
||||||
so as to flatten the rep-ed layout as much as possible, the reason
|
the outer variant, so as to flatten the rep-ed layout as much as
|
||||||
being that we cannot do any flattening when a subtype statically
|
possible, the reason being that we cannot do any flattening when
|
||||||
selects a variant later on, for example for an aggregate. */
|
a subtype statically selects a variant later on, for example for
|
||||||
|
an aggregate. */
|
||||||
has_rep
|
has_rep
|
||||||
= components_to_record (Component_List (variant), gnat_record_type,
|
= components_to_record (Component_List (variant), gnat_record_type,
|
||||||
NULL_TREE, gnu_variant_type, packed,
|
NULL_TREE, gnu_variant_type, packed,
|
||||||
@ -8078,7 +8093,9 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
|
|||||||
unchecked_union, true, needs_xv_encodings,
|
unchecked_union, true, needs_xv_encodings,
|
||||||
true, this_first_free_pos,
|
true, this_first_free_pos,
|
||||||
(all_rep || this_first_free_pos)
|
(all_rep || this_first_free_pos)
|
||||||
&& !(in_variant && unchecked_union)
|
&& !(unchecked_union
|
||||||
|
&& gnu_field_list
|
||||||
|
&& innermost_variant_level)
|
||||||
? NULL : &gnu_rep_list);
|
? NULL : &gnu_rep_list);
|
||||||
|
|
||||||
/* Translate the qualifier and annotate the GNAT node. */
|
/* Translate the qualifier and annotate the GNAT node. */
|
||||||
|
Loading…
Reference in New Issue
Block a user