aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2019-05-28 07:36:02 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2019-05-28 07:36:02 +0000
commitf65f371bcff00263f9e870d546b580caebd953b3 (patch)
treec9d1a1e2186cd885fe778b09942d0358616a012e
parente6ca6782acfa8b126c6abb6bcd9026572217525d (diff)
downloadgcc-f65f371bcff00263f9e870d546b580caebd953b3.zip
gcc-f65f371bcff00263f9e870d546b580caebd953b3.tar.gz
gcc-f65f371bcff00263f9e870d546b580caebd953b3.tar.bz2
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
-rw-r--r--gcc/ada/ChangeLog8
-rw-r--r--gcc/ada/gcc-interface/decl.c2
-rw-r--r--gcc/ada/gcc-interface/utils.c38
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/specs/discr5.ads57
5 files changed, 90 insertions, 19 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 6acef36..8c22c32 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,13 @@
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.
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 9082d44..dc23743 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -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);
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index d090d09..dbf7c18 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 633ecfc..0bf055b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
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>
diff --git a/gcc/testsuite/gnat.dg/specs/discr5.ads b/gcc/testsuite/gnat.dg/specs/discr5.ads
new file mode 100644
index 0000000..c265723
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/discr5.ads
@@ -0,0 +1,57 @@
+-- { 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;