===================================================================
@@ -177,7 +177,6 @@ static void check_ok_for_atomic (tree, E
static tree create_field_decl_from (tree, tree, tree, tree, tree,
VEC(subst_pair,heap) *);
static tree get_rep_part (tree);
-static tree get_variant_part (tree);
static tree create_variant_part_from (tree, VEC(variant_desc,heap) *, tree,
tree, VEC(subst_pair,heap) *);
static void copy_and_substitute_in_size (tree, tree, VEC(subst_pair,heap) *);
@@ -8509,7 +8508,7 @@ get_rep_part (tree record_type)
/* Return the variant part of RECORD_TYPE, if any. Otherwise return NULL. */
-static tree
+tree
get_variant_part (tree record_type)
{
tree field;
===================================================================
@@ -193,15 +193,21 @@ find_common_type (tree t1, tree t2)
calling into build_binary_op), some others are really expected and we
have to be careful. */
- /* We must prevent writing more than what the target may hold if this is for
+ /* We must avoid writing more than what the target can hold if this is for
an assignment and the case of tagged types is handled in build_binary_op
- so use the lhs type if it is known to be smaller, or of constant size and
- the rhs type is not, whatever the modes. We also force t1 in case of
+ so we use the lhs type if it is known to be smaller or of constant size
+ and the rhs type is not, whatever the modes. We also force t1 in case of
constant size equality to minimize occurrences of view conversions on the
- lhs of assignments. */
+ lhs of an assignment, except for the case of record types with a variant
+ part on the lhs but not on the rhs to make the conversion simpler. */
if (TREE_CONSTANT (TYPE_SIZE (t1))
&& (!TREE_CONSTANT (TYPE_SIZE (t2))
- || !tree_int_cst_lt (TYPE_SIZE (t2), TYPE_SIZE (t1))))
+ || tree_int_cst_lt (TYPE_SIZE (t1), TYPE_SIZE (t2))
+ || (TYPE_SIZE (t1) == TYPE_SIZE (t2)
+ && !(TREE_CODE (t1) == RECORD_TYPE
+ && TREE_CODE (t2) == RECORD_TYPE
+ && get_variant_part (t1) != NULL_TREE
+ && get_variant_part (t2) == NULL_TREE))))
return t1;
/* Otherwise, if the lhs type is non-BLKmode, use it. Note that we know
===================================================================
@@ -150,6 +150,9 @@ extern tree choices_to_gnu (tree operand
extern void annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size,
bool by_ref, bool by_double_ref);
+/* Return the variant part of RECORD_TYPE, if any. Otherwise return NULL. */
+extern tree get_variant_part (tree record_type);
+
/* Given a type T, a FIELD_DECL F, and a replacement value R, return a new
type with all size expressions that contain F updated by replacing F
with R. If F is NULL_TREE, always make a new RECORD_TYPE, even if