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> 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 * gcc-interface/utils.c (gnat_internal_attribute_table): Add support
for stack_protect attribute. for stack_protect attribute.
(handle_stack_protect_attribute): New static function. (handle_stack_protect_attribute): New static function.
......
...@@ -8162,6 +8162,8 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type, ...@@ -8162,6 +8162,8 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
gnu_field_list = gnu_rep_list; gnu_field_list = gnu_rep_list;
else 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_rep_type)
= TYPE_REVERSE_STORAGE_ORDER (gnu_record_type); = TYPE_REVERSE_STORAGE_ORDER (gnu_record_type);
finish_record_type (gnu_rep_type, gnu_rep_list, 1, debug_info); 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, ...@@ -1863,6 +1863,9 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
else else
this_ada_size = this_size; 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. */ /* Clear DECL_BIT_FIELD for the cases layout_decl does not handle. */
if (DECL_BIT_FIELD (field) if (DECL_BIT_FIELD (field)
&& operand_equal_p (this_size, TYPE_SIZE (type), 0)) && 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, ...@@ -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 /* 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 not supported by the DECL_BIT_FIELD_REPRESENTATIVE machinery because
the variant part is always the last field in the list. */ the variant part is always the last field in the list. */
if (DECL_INTERNAL_P (field) if (variant_part_at_zero)
&& TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
&& integer_zerop (pos))
DECL_BIT_FIELD_TYPE (field) = NULL_TREE; DECL_BIT_FIELD_TYPE (field) = NULL_TREE;
/* If we still have DECL_BIT_FIELD set at this point, we know that the /* 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, ...@@ -1941,18 +1942,18 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
case RECORD_TYPE: case RECORD_TYPE:
/* Since we know here that all fields are sorted in order of /* Since we know here that all fields are sorted in order of
increasing bit position, the size of the record is one increasing bit position, the size of the record is one
higher than the ending bit of the last field processed higher than the ending bit of the last field processed,
unless we have a rep clause, since in that case we might unless we have a variant part at offset 0, since in this
have a field outside a QUAL_UNION_TYPE that has a higher ending case we might have a field outside the variant part that
position. So use a MAX in that case. Also, if this field is a has a higher ending position; so use a MAX in this case.
QUAL_UNION_TYPE, we need to take into account the previous size in Also, if this field is a QUAL_UNION_TYPE, we need to take
the case of empty variants. */ into account the previous size in the case of empty variants. */
ada_size ada_size
= merge_sizes (ada_size, pos, this_ada_size, = merge_sizes (ada_size, pos, this_ada_size, variant_part,
TREE_CODE (type) == QUAL_UNION_TYPE, rep_level > 0); variant_part_at_zero);
size size
= merge_sizes (size, pos, this_size, = merge_sizes (size, pos, this_size, variant_part,
TREE_CODE (type) == QUAL_UNION_TYPE, rep_level > 0); variant_part_at_zero);
break; break;
default: default:
...@@ -2233,13 +2234,12 @@ rest_of_record_type_compilation (tree record_type) ...@@ -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 /* 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 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 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, 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. Return an expression for the size. */
static tree static tree
merge_sizes (tree last_size, tree first_bit, tree size, bool special, merge_sizes (tree last_size, tree first_bit, tree size, bool special, bool max)
bool has_rep)
{ {
tree type = TREE_TYPE (last_size); tree type = TREE_TYPE (last_size);
tree new_size; tree new_size;
...@@ -2247,7 +2247,7 @@ merge_sizes (tree last_size, tree first_bit, tree size, bool special, ...@@ -2247,7 +2247,7 @@ merge_sizes (tree last_size, tree first_bit, tree size, bool special,
if (!special || TREE_CODE (size) != COND_EXPR) if (!special || TREE_CODE (size) != COND_EXPR)
{ {
new_size = size_binop (PLUS_EXPR, first_bit, size); new_size = size_binop (PLUS_EXPR, first_bit, size);
if (has_rep) if (max)
new_size = size_binop (MAX_EXPR, last_size, new_size); 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, ...@@ -2256,11 +2256,11 @@ merge_sizes (tree last_size, tree first_bit, tree size, bool special,
integer_zerop (TREE_OPERAND (size, 1)) integer_zerop (TREE_OPERAND (size, 1))
? last_size : merge_sizes (last_size, first_bit, ? last_size : merge_sizes (last_size, first_bit,
TREE_OPERAND (size, 1), TREE_OPERAND (size, 1),
1, has_rep), 1, max),
integer_zerop (TREE_OPERAND (size, 2)) integer_zerop (TREE_OPERAND (size, 2))
? last_size : merge_sizes (last_size, first_bit, ? last_size : merge_sizes (last_size, first_bit,
TREE_OPERAND (size, 2), TREE_OPERAND (size, 2),
1, has_rep)); 1, max));
/* We don't need any NON_VALUE_EXPRs and they can confuse us (especially /* 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 when fed through SUBSTITUTE_IN_EXPR) into thinking that a constant
......
2019-05-28 Eric Botcazou <ebotcazou@adacore.com> 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. * gnat.dg/prefetch1.ad[sb]: New test.
2019-05-27 Iain Sandoe <iain@sandoe.co.uk> 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