Commit f65f371b by Eric Botcazou Committed by Eric Botcazou

decl.c (components_to_record): Set a name on the type created for the REP part, if any.

	* gcc-interface/decl.c (components_to_record): Set a name on the type
	created for the REP part, if any.
	* gcc-interface/utils.c (finish_record_type): Only take the maximum
	when merging sizes for a variant part at offset 0.
	(merge_sizes): Rename has_rep parameter into max.

From-SVN: r271681
parent e6ca6782
2019-05-28 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (components_to_record): Set a name on the type
created for the REP part, if any.
* gcc-interface/utils.c (finish_record_type): Only take the maximum
when merging sizes for a variant part at offset 0.
(merge_sizes): Rename has_rep parameter into max.
2019-05-28 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/utils.c (gnat_internal_attribute_table): Add support
for stack_protect attribute.
(handle_stack_protect_attribute): New static function.
......
......@@ -8162,6 +8162,8 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
gnu_field_list = gnu_rep_list;
else
{
TYPE_NAME (gnu_rep_type)
= create_concat_name (gnat_record_type, "REP");
TYPE_REVERSE_STORAGE_ORDER (gnu_rep_type)
= TYPE_REVERSE_STORAGE_ORDER (gnu_record_type);
finish_record_type (gnu_rep_type, gnu_rep_list, 1, debug_info);
......
......@@ -1863,6 +1863,9 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
else
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)
&& operand_equal_p (this_size, TYPE_SIZE (type), 0))
......@@ -1904,9 +1907,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 (DECL_INTERNAL_P (field)
&& TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
&& integer_zerop (pos))
if (variant_part_at_zero)
DECL_BIT_FIELD_TYPE (field) = NULL_TREE;
/* If we still have DECL_BIT_FIELD set at this point, we know that the
......@@ -1941,18 +1942,18 @@ 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 rep clause, since in that case we might
have a field outside a QUAL_UNION_TYPE that has a higher ending
position. So use a MAX in that 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 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. */
ada_size
= merge_sizes (ada_size, pos, this_ada_size,
TREE_CODE (type) == QUAL_UNION_TYPE, rep_level > 0);
= merge_sizes (ada_size, pos, this_ada_size, variant_part,
variant_part_at_zero);
size
= merge_sizes (size, pos, this_size,
TREE_CODE (type) == QUAL_UNION_TYPE, rep_level > 0);
= merge_sizes (size, pos, this_size, variant_part,
variant_part_at_zero);
break;
default:
......@@ -2233,13 +2234,12 @@ 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 HAS_REP is true, we take the
replace a value of zero with the old size. 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. */
static tree
merge_sizes (tree last_size, tree first_bit, tree size, bool special,
bool has_rep)
merge_sizes (tree last_size, tree first_bit, tree size, bool special, bool max)
{
tree type = TREE_TYPE (last_size);
tree new_size;
......@@ -2247,7 +2247,7 @@ merge_sizes (tree last_size, tree first_bit, tree size, bool special,
if (!special || TREE_CODE (size) != COND_EXPR)
{
new_size = size_binop (PLUS_EXPR, first_bit, size);
if (has_rep)
if (max)
new_size = size_binop (MAX_EXPR, last_size, new_size);
}
......@@ -2256,11 +2256,11 @@ merge_sizes (tree last_size, tree first_bit, tree size, bool special,
integer_zerop (TREE_OPERAND (size, 1))
? last_size : merge_sizes (last_size, first_bit,
TREE_OPERAND (size, 1),
1, has_rep),
1, max),
integer_zerop (TREE_OPERAND (size, 2))
? last_size : merge_sizes (last_size, first_bit,
TREE_OPERAND (size, 2),
1, has_rep));
1, max));
/* 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
......
2019-05-28 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/discr5.ads: New test.
2019-05-28 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/prefetch1.ad[sb]: New test.
2019-05-27 Iain Sandoe <iain@sandoe.co.uk>
......
-- { dg-do compile }
with System;
package Discr5 is
X, Y : Boolean;
type R (D : Boolean := False) is tagged limited record
F : Integer;
case D is
when True =>
F1, F2 : Integer;
when False =>
null;
end case;
end record;
for R use record
F1 at 100 range 0..31;
end record;
subtype Rt is R(True);
subtype Rf is R(False);
type R1 (D1 : Boolean) is new R (X) with record
FF : Float;
case D1 is
when True =>
F3, F4 : Float;
when False =>
null;
end case;
end record;
for R1 use record
F4 at 200 range 0..31;
end record;
subtype R1t is R1 (True);
subtype R1f is R1 (False);
type R2 (D2 : Boolean) is new R1 (Y) with record
FFF: System.Address;
case D2 is
when True =>
F5, F6: System.Address;
when False =>
null;
end case;
end record;
for R2 use record
F6 at 300 range 0..63;
end record;
subtype R2t is R2 (True);
subtype R2f is R2 (False);
end Discr5;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment