decl.c (rm_size): Take into account the padding in the case of a record type containi...
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 14 Dec 2018 11:08:15 +0000 (11:08 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 14 Dec 2018 11:08:15 +0000 (11:08 +0000)
* gcc-interface/decl.c (rm_size): Take into account the padding in
the case of a record type containing a template.
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Size>: Likewise.
Do not subtract the padded size for Max_Size_In_Storage_Elements.
<Attr_Descriptor_Size>: Tweak comment.

From-SVN: r267131

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/max_size.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/max_size_pkg.ads [new file with mode: 0644]

index 9fa05898b2db15cdaf28228a1d73f109d9ea0eb8..ba974cdcb03f92a285cffc6ebb2d2df675a96b37 100644 (file)
@@ -1,3 +1,11 @@
+2018-12-14  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (rm_size): Take into account the padding in
+       the case of a record type containing a template.
+       * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Size>: Likewise.
+       Do not subtract the padded size for Max_Size_In_Storage_Elements.
+       <Attr_Descriptor_Size>: Tweak comment.
+
 2018-12-14  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/decl.c (choices_to_gnu): Directly use a naked boolean
index 0ad06f1a9f1149efc9217d6f55cef4e8d3a84b03..df55f4893b7bfa302328acf2168a411a308489c8 100644 (file)
@@ -10049,13 +10049,14 @@ rm_size (tree gnu_type)
   if (INTEGRAL_TYPE_P (gnu_type) && TYPE_RM_SIZE (gnu_type))
     return TYPE_RM_SIZE (gnu_type);
 
-  /* Return the RM size of the actual data plus the size of the template.  */
+  /* If the type contains a template, return the padded size of the template
+     plus the RM size of the actual data.  */
   if (TREE_CODE (gnu_type) == RECORD_TYPE
       && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
     return
       size_binop (PLUS_EXPR,
-                 rm_size (TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type)))),
-                 DECL_SIZE (TYPE_FIELDS (gnu_type)));
+                 bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type))),
+                 rm_size (TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type)))));
 
   /* For record or union types, we store the size explicitly.  */
   if (RECORD_OR_UNION_TYPE_P (gnu_type)
index 35b71ef838ab66506f51e05ef6eda3ce645b3631..620dbd3d36d097dc7a0069dad9486d5a29c690ce 100644 (file)
@@ -2308,10 +2308,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
       gnu_type = TREE_TYPE (gnu_prefix);
 
       /* Replace an unconstrained array type with the type of the underlying
-        array.  We can't do this with a call to maybe_unconstrained_array
-        since we may have a TYPE_DECL.  For 'Max_Size_In_Storage_Elements,
-        use the record type that will be used to allocate the object and its
-        template.  */
+        array, except for 'Max_Size_In_Storage_Elements because we need to
+        return the (maximum) size requested for an allocator.  */
       if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
        {
          gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
@@ -2375,11 +2373,15 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
            gnu_result = substitute_placeholder_in_expr (gnu_result, gnu_expr);
        }
 
-      /* If the type contains a template, subtract its size.  */
+      /* If the type contains a template, subtract the padded size of the
+        template, except for 'Max_Size_In_Storage_Elements because we need
+        to return the (maximum) size requested for an allocator.  */
       if (TREE_CODE (gnu_type) == RECORD_TYPE
-         && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
-       gnu_result = size_binop (MINUS_EXPR, gnu_result,
-                                DECL_SIZE (TYPE_FIELDS (gnu_type)));
+         && TYPE_CONTAINS_TEMPLATE_P (gnu_type)
+         && attribute != Attr_Max_Size_In_Storage_Elements)
+       gnu_result
+         = size_binop (MINUS_EXPR, gnu_result,
+                       bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type))));
 
       /* For 'Max_Size_In_Storage_Elements, adjust the unit.  */
       if (attribute == Attr_Max_Size_In_Storage_Elements)
@@ -2856,8 +2858,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
       gnu_type = TREE_TYPE (gnu_prefix);
       gcc_assert (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE);
 
-      /* What we want is the offset of the ARRAY field in the record
-        that the thin pointer designates.  */
+      /* Return the padded size of the template in the object record type.  */
       gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
       gnu_result = bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type)));
       gnu_result_type = get_unpadded_type (Etype (gnat_node));
index 3cfdfaec305e983d06f1e8ebd416645015af8182..4e0e910ebf1bb902c8938285757fe6fccbbdc9a6 100644 (file)
@@ -1,3 +1,8 @@
+2018-12-14  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/max_size.adb: New test.
+       * gnat.dg/max_size_pkg.ads: Likewise.
+
 2018-12-14  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * gcc.target/arc/milli-1.c: New test.
diff --git a/gcc/testsuite/gnat.dg/max_size.adb b/gcc/testsuite/gnat.dg/max_size.adb
new file mode 100644 (file)
index 0000000..28562c1
--- /dev/null
@@ -0,0 +1,13 @@
+-- { dg-do run }
+
+with Max_Size_Pkg; use Max_Size_Pkg;
+
+procedure Max_Size is
+begin
+  if Arr1'Max_Size_In_Storage_Elements /= 7 then
+    raise Program_Error;
+  end if;
+  if Arr2'Max_Size_In_Storage_Elements /= 24 then
+    raise Program_Error;
+  end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/max_size_pkg.ads b/gcc/testsuite/gnat.dg/max_size_pkg.ads
new file mode 100644 (file)
index 0000000..d4850c1
--- /dev/null
@@ -0,0 +1,9 @@
+package Max_Size_Pkg is
+
+  type Index is range 1 .. 5;
+
+  type Arr1 is array (Index range <>) of Short_Short_Integer;
+
+  type Arr2 is array (Index range <>) of Integer;
+
+end Max_Size_Pkg;