aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog9
-rw-r--r--gcc/ada/gcc-interface/trans.c42
2 files changed, 33 insertions, 18 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 4db444a..3b4d5a3 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,14 @@
2019-05-28 Eric Botcazou <ebotcazou@adacore.com>
+ * gcc-interface/trans.c (lvalue_required_for_attribute_p): Return 0
+ for 'Size too.
+ (Identifier_to_gnu): Use the actual subtype for a reference to a
+ packed array in a return statement.
+ (Attribute_to_gnu) <Attr_Size>: Do not strip VIEW_CONVERT_EXPRs from
+ the prefix in every case.
+
+2019-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
* gcc-interface/trans.c (gnat_to_gnu): Remove superfluous tests on
Backend_Overflow_Checks_On_Target and rework comments.
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index f5cc318..e2d2dda 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -778,6 +778,7 @@ lvalue_required_for_attribute_p (Node_Id gnat_node)
case Attr_Range_Length:
case Attr_Length:
case Attr_Object_Size:
+ case Attr_Size:
case Attr_Value_Size:
case Attr_Component_Size:
case Attr_Descriptor_Size:
@@ -797,7 +798,6 @@ lvalue_required_for_attribute_p (Node_Id gnat_node)
case Attr_Unrestricted_Access:
case Attr_Code_Address:
case Attr_Pool_Address:
- case Attr_Size:
case Attr_Alignment:
case Attr_Bit_Position:
case Attr_Position:
@@ -1112,12 +1112,15 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
{
/* We use the Actual_Subtype only if it has already been elaborated,
as we may be invoked precisely during its elaboration, otherwise
- the Etype. Avoid using it for packed arrays to simplify things. */
+ the Etype. Avoid using it for packed arrays to simplify things,
+ except in a return statement because we need the actual size and
+ the front-end does not make it explicit in this case. */
if ((Ekind (gnat_entity) == E_Constant
|| Ekind (gnat_entity) == E_Variable
|| Is_Formal (gnat_entity))
&& !(Is_Array_Type (Etype (gnat_entity))
- && Present (Packed_Array_Impl_Type (Etype (gnat_entity))))
+ && Present (Packed_Array_Impl_Type (Etype (gnat_entity)))
+ && Nkind (Parent (gnat_node)) != N_Simple_Return_Statement)
&& Present (Actual_Subtype (gnat_entity))
&& present_gnu_tree (Actual_Subtype (gnat_entity)))
gnat_result_type = Actual_Subtype (gnat_entity);
@@ -2314,21 +2317,24 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
case Attr_Object_Size:
case Attr_Value_Size:
case Attr_Max_Size_In_Storage_Elements:
- gnu_expr = gnu_prefix;
-
- /* Remove NOPs and conversions between original and packable version
- from GNU_EXPR, and conversions from GNU_PREFIX. We use GNU_EXPR
- to see if a COMPONENT_REF was involved. */
- while (TREE_CODE (gnu_expr) == NOP_EXPR
- || (TREE_CODE (gnu_expr) == VIEW_CONVERT_EXPR
- && TREE_CODE (TREE_TYPE (gnu_expr)) == RECORD_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))
+ /* Strip NOPs, conversions between original and packable versions, and
+ unpadding from GNU_PREFIX. Note that we cannot simply strip every
+ VIEW_CONVERT_EXPR because some of them may give the actual size, e.g.
+ for nominally unconstrained packed array. We use GNU_EXPR to see
+ if a COMPONENT_REF was involved. */
+ while (CONVERT_EXPR_P (gnu_prefix)
+ || TREE_CODE (gnu_prefix) == NON_LVALUE_EXPR
+ || (TREE_CODE (gnu_prefix) == VIEW_CONVERT_EXPR
+ && TREE_CODE (TREE_TYPE (gnu_prefix)) == RECORD_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))
== RECORD_TYPE
- && TYPE_NAME (TREE_TYPE (gnu_expr))
- == TYPE_NAME (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))))
- gnu_expr = TREE_OPERAND (gnu_expr, 0);
-
- gnu_prefix = remove_conversions (gnu_prefix, true);
+ && TYPE_NAME (TREE_TYPE (gnu_prefix))
+ == TYPE_NAME (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))))
+ gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
+ gnu_expr = gnu_prefix;
+ if (TREE_CODE (gnu_prefix) == COMPONENT_REF
+ && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))))
+ gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
prefix_unused = true;
gnu_type = TREE_TYPE (gnu_prefix);
@@ -2391,7 +2397,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
/* Deal with a self-referential size by qualifying the size with the
object or returning the maximum size for a type. */
if (TREE_CODE (gnu_prefix) != TYPE_DECL)
- gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_expr);
+ gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
else if (CONTAINS_PLACEHOLDER_P (gnu_result))
gnu_result = max_size (gnu_result, true);