aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-02-03 08:48:19 -0800
committerIan Lance Taylor <iant@golang.org>2021-02-03 08:48:19 -0800
commit305e9d2c7815e90a29bbde1e3a7cd776861f4d7c (patch)
tree32dedad81f42b67729aef302069fcee11132d215 /gcc/ada/gcc-interface/utils.c
parent8910f1cd79445bbe2da01f8ccf7c37909349529e (diff)
parent530203d6e3244c25eda4124f0fa5756ca9a5683e (diff)
downloadgcc-305e9d2c7815e90a29bbde1e3a7cd776861f4d7c.zip
gcc-305e9d2c7815e90a29bbde1e3a7cd776861f4d7c.tar.gz
gcc-305e9d2c7815e90a29bbde1e3a7cd776861f4d7c.tar.bz2
Merge from trunk revision 530203d6e3244c25eda4124f0fa5756ca9a5683e.
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index c503bfb..952f032 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -467,6 +467,11 @@ make_dummy_type (Entity_Id gnat_type)
= create_type_stub_decl (TYPE_NAME (gnu_type), gnu_type);
if (Is_By_Reference_Type (gnat_equiv))
TYPE_BY_REFERENCE_P (gnu_type) = 1;
+ if (Has_Discriminants (gnat_equiv))
+ decl_attributes (&gnu_type,
+ tree_cons (get_identifier ("may_alias"), NULL_TREE,
+ NULL_TREE),
+ ATTR_FLAG_TYPE_IN_PLACE);
SET_DUMMY_NODE (gnat_equiv, gnu_type);
@@ -516,10 +521,10 @@ build_dummy_unc_pointer_types (Entity_Id gnat_desig_type, tree gnu_desig_type)
= create_type_stub_decl (create_concat_name (gnat_desig_type, "XUP"),
gnu_fat_type);
fields = create_field_decl (get_identifier ("P_ARRAY"), gnu_ptr_array,
- gnu_fat_type, NULL_TREE, NULL_TREE, 0, 0);
+ gnu_fat_type, NULL_TREE, NULL_TREE, 0, 1);
DECL_CHAIN (fields)
= create_field_decl (get_identifier ("P_BOUNDS"), gnu_ptr_template,
- gnu_fat_type, NULL_TREE, NULL_TREE, 0, 0);
+ gnu_fat_type, NULL_TREE, NULL_TREE, 0, 1);
finish_fat_pointer_type (gnu_fat_type, fields);
SET_TYPE_UNCONSTRAINED_ARRAY (gnu_fat_type, gnu_desig_type);
/* Suppress debug info until after the type is completed. */
@@ -2046,7 +2051,6 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
this_ada_size = this_size;
const bool variant_part = (TREE_CODE (type) == QUAL_UNION_TYPE);
- const bool variant_part_at_zero = variant_part && integer_zerop (pos);
/* Clear DECL_BIT_FIELD for the cases layout_decl does not handle. */
if (DECL_BIT_FIELD (field)
@@ -2089,7 +2093,7 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
/* Clear DECL_BIT_FIELD_TYPE for a variant part at offset 0, it's simply
not supported by the DECL_BIT_FIELD_REPRESENTATIVE machinery because
the variant part is always the last field in the list. */
- if (variant_part_at_zero)
+ if (variant_part && integer_zerop (pos))
DECL_BIT_FIELD_TYPE (field) = NULL_TREE;
/* If we still have DECL_BIT_FIELD set at this point, we know that the
@@ -2124,18 +2128,20 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
case RECORD_TYPE:
/* Since we know here that all fields are sorted in order of
increasing bit position, the size of the record is one
- higher than the ending bit of the last field processed,
- unless we have a variant part at offset 0, since in this
- case we might have a field outside the variant part that
- has a higher ending position; so use a MAX in this case.
- Also, if this field is a QUAL_UNION_TYPE, we need to take
- into account the previous size in the case of empty variants. */
+ higher than the ending bit of the last field processed
+ unless we have a rep clause, because we might be processing
+ the REP part of a record with a variant part for which the
+ variant part has a rep clause but not the fixed part, in
+ which case this REP part may contain overlapping fields
+ and thus needs to be treated like a union tyoe above, so
+ use a MAX in that case. Also, if this field is a variant
+ part, we need to take into account the previous size in
+ the case of empty variants. */
ada_size
- = merge_sizes (ada_size, pos, this_ada_size, variant_part,
- variant_part_at_zero);
+ = merge_sizes (ada_size, pos, this_ada_size, rep_level > 0,
+ variant_part);
size
- = merge_sizes (size, pos, this_size, variant_part,
- variant_part_at_zero);
+ = merge_sizes (size, pos, this_size, rep_level > 0, variant_part);
break;
default:
@@ -2427,14 +2433,14 @@ rest_of_record_type_compilation (tree record_type)
}
/* Utility function of above to merge LAST_SIZE, the previous size of a record
- with FIRST_BIT and SIZE that describe a field. SPECIAL is true if this
- represents a QUAL_UNION_TYPE in which case we must look for COND_EXPRs and
- replace a value of zero with the old size. If MAX is true, we take the
+ with FIRST_BIT and SIZE that describe a field. If MAX is true, we take the
MAX of the end position of this field with LAST_SIZE. In all other cases,
- we use FIRST_BIT plus SIZE. Return an expression for the size. */
+ we use FIRST_BIT plus SIZE. SPECIAL is true if it's for a QUAL_UNION_TYPE,
+ in which case we must look for COND_EXPRs and replace a value of zero with
+ the old size. Return an expression for the size. */
static tree
-merge_sizes (tree last_size, tree first_bit, tree size, bool special, bool max)
+merge_sizes (tree last_size, tree first_bit, tree size, bool max, bool special)
{
tree type = TREE_TYPE (last_size);
tree new_size;
@@ -2451,11 +2457,11 @@ merge_sizes (tree last_size, tree first_bit, tree size, bool special, bool max)
integer_zerop (TREE_OPERAND (size, 1))
? last_size : merge_sizes (last_size, first_bit,
TREE_OPERAND (size, 1),
- 1, max),
+ max, special),
integer_zerop (TREE_OPERAND (size, 2))
? last_size : merge_sizes (last_size, first_bit,
TREE_OPERAND (size, 2),
- 1, max));
+ max, special));
/* We don't need any NON_VALUE_EXPRs and they can confuse us (especially
when fed through SUBSTITUTE_IN_EXPR) into thinking that a constant