trans.c (gnat_to_gnu): Minor tweak.
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 8 Feb 2019 11:37:40 +0000 (11:37 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 8 Feb 2019 11:37:40 +0000 (11:37 +0000)
* gcc-interface/trans.c (gnat_to_gnu) <N_Aggregate>: Minor tweak.
* gcc-interface/utils.c (convert): Do not pad when doing an unchecked
conversion here.  Use TREE_CONSTANT throughout the function.
(unchecked_convert): Also pad if the source is a CONSTRUCTOR and the
destination is a more aligned array type or a larger aggregate type,
but not between original and packable versions of a type.

From-SVN: r268679

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

index b120650cda8c7eab1f3c2ee8dacad57330899817..9003beccacecdeb754cc3196b120040885cb5612 100644 (file)
@@ -1,3 +1,12 @@
+2019-02-08  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/trans.c (gnat_to_gnu) <N_Aggregate>: Minor tweak.
+       * gcc-interface/utils.c (convert): Do not pad when doing an unchecked
+       conversion here.  Use TREE_CONSTANT throughout the function.
+       (unchecked_convert): Also pad if the source is a CONSTRUCTOR and the
+       destination is a more aligned array type or a larger aggregate type,
+       but not between original and packable versions of a type.
+
 2019-02-08  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/utils.c (max_size) <tcc_unary>: Be prepared for an
index 71b626b291fae4304e69cfbe31a890cbf57f8109..155cb4b27abc3ac6063c4f630b400714c244b258 100644 (file)
@@ -7230,13 +7230,10 @@ gnat_to_gnu (Node_Id gnat_node)
       {
        tree gnu_aggr_type;
 
-       /* ??? It is wrong to evaluate the type now, but there doesn't
-          seem to be any other practical way of doing it.  */
-
+       /* Check that this aggregate has not slipped through the cracks.  */
        gcc_assert (!Expansion_Delayed (gnat_node));
 
-       gnu_aggr_type = gnu_result_type
-         = get_unpadded_type (Etype (gnat_node));
+       gnu_result_type = get_unpadded_type (Etype (gnat_node));
 
        if (TREE_CODE (gnu_result_type) == RECORD_TYPE
            && TYPE_CONTAINS_TEMPLATE_P (gnu_result_type))
@@ -7244,6 +7241,8 @@ gnat_to_gnu (Node_Id gnat_node)
            = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_result_type)));
        else if (TREE_CODE (gnu_result_type) == VECTOR_TYPE)
          gnu_aggr_type = TYPE_REPRESENTATIVE_ARRAY (gnu_result_type);
+       else
+         gnu_aggr_type = gnu_result_type;
 
        if (Null_Record_Present (gnat_node))
          gnu_result = gnat_build_constructor (gnu_aggr_type, NULL);
index 65b7e0f3cac9307da0ab10fcf39ed09d995944fa..da4e1009e8c5fb522de3317193155854102de395 100644 (file)
@@ -4356,19 +4356,12 @@ convert (tree type, tree expr)
 
       /* If the inner type is of self-referential size and the expression type
         is a record, do this as an unchecked conversion unless both types are
-        essentially the same.  But first pad the expression if possible to
-        have the same size on both sides.  */
+        essentially the same.  */
       if (ecode == RECORD_TYPE
          && CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type)))
          && TYPE_MAIN_VARIANT (etype)
             != TYPE_MAIN_VARIANT (TREE_TYPE (TYPE_FIELDS (type))))
-       {
-         if (TREE_CODE (TYPE_SIZE (etype)) == INTEGER_CST)
-           expr = convert (maybe_pad_type (etype, TYPE_SIZE (type), 0, Empty,
-                                           false, false, false, true),
-                           expr);
-         return unchecked_convert (type, expr, false);
-       }
+       return unchecked_convert (type, expr, false);
 
       /* If we are converting between array types with variable size, do the
         final conversion as an unchecked conversion, again to avoid the need
@@ -4483,9 +4476,9 @@ convert (tree type, tree expr)
     case STRING_CST:
       /* If we are converting a STRING_CST to another constrained array type,
         just make a new one in the proper type.  */
-      if (code == ecode && AGGREGATE_TYPE_P (etype)
-         && !(TREE_CODE (TYPE_SIZE (etype)) == INTEGER_CST
-              && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
+      if (code == ecode
+         && !(TREE_CONSTANT (TYPE_SIZE (etype))
+              && !TREE_CONSTANT (TYPE_SIZE (type))))
        {
          expr = copy_node (expr);
          TREE_TYPE (expr) = type;
@@ -5332,7 +5325,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
      so we skip all expressions that are references.  */
   else if (!REFERENCE_CLASS_P (expr)
           && !AGGREGATE_TYPE_P (etype)
-          && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+          && TREE_CONSTANT (TYPE_SIZE (type))
           && (c = tree_int_cst_compare (TYPE_SIZE (etype), TYPE_SIZE (type))))
     {
       if (c < 0)
@@ -5380,10 +5373,13 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
       return unchecked_convert (type, expr, notrunc_p);
     }
 
-  /* If we are converting a CONSTRUCTOR to a more aligned RECORD_TYPE, bump
-     the alignment of the CONSTRUCTOR to speed up the copy operation.  */
+  /* If we are converting a CONSTRUCTOR to a more aligned aggregate type, bump
+     the alignment of the CONSTRUCTOR to speed up the copy operation.  But do
+     not do it for a conversion between original and packable version to avoid
+     an infinite recursion.  */
   else if (TREE_CODE (expr) == CONSTRUCTOR
-          && code == RECORD_TYPE
+          && AGGREGATE_TYPE_P (type)
+          && TYPE_NAME (type) != TYPE_NAME (etype)
           && TYPE_ALIGN (etype) < TYPE_ALIGN (type))
     {
       expr = convert (maybe_pad_type (etype, NULL_TREE, TYPE_ALIGN (type),
@@ -5392,6 +5388,23 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
       return unchecked_convert (type, expr, notrunc_p);
     }
 
+  /* If we are converting a CONSTRUCTOR to a larger aggregate type, bump the
+     size of the CONSTRUCTOR to make sure there are enough allocated bytes.
+     But do not do it for a conversion between original and packable version
+     to avoid an infinite recursion.  */
+  else if (TREE_CODE (expr) == CONSTRUCTOR
+          && AGGREGATE_TYPE_P (type)
+          && TYPE_NAME (type) != TYPE_NAME (etype)
+          && TREE_CONSTANT (TYPE_SIZE (type))
+          && (!TREE_CONSTANT (TYPE_SIZE (etype))
+              || tree_int_cst_lt (TYPE_SIZE (etype), TYPE_SIZE (type))))
+    {
+      expr = convert (maybe_pad_type (etype, TYPE_SIZE (type), 0,
+                                     Empty, false, false, false, true),
+                     expr);
+      return unchecked_convert (type, expr, notrunc_p);
+    }
+
   /* Otherwise, just build a VIEW_CONVERT_EXPR of the expression.  */
   else
     {