trans.c (lvalue_required_for_attribute_p): Return 0 for 'Size too.
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 28 May 2019 08:25:32 +0000 (08:25 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 28 May 2019 08:25:32 +0000 (08:25 +0000)
* 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.

From-SVN: r271691

gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c

index 4db444ab4572245be4f544e657d01c6f6b80275c..3b4d5a332d6163d7f30a89ab982d11febfcac542 100644 (file)
@@ -1,3 +1,12 @@
+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
index f5cc31876a590e211c58488c68237e45e2e0e981..e2d2ddae3fed0de2d16974e399e039c2e3df35a4 100644 (file)
@@ -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);