From 65e0a92b2353927e50a26a3a0628a36aebc85b40 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 14 Dec 2018 11:08:15 +0000 Subject: [PATCH] decl.c (rm_size): Take into account the padding in the case of a record type containing a template. * 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) : Likewise. Do not subtract the padded size for Max_Size_In_Storage_Elements. : Tweak comment. From-SVN: r267131 --- gcc/ada/ChangeLog | 8 ++++++++ gcc/ada/gcc-interface/decl.c | 7 ++++--- gcc/ada/gcc-interface/trans.c | 21 +++++++++++---------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gnat.dg/max_size.adb | 13 +++++++++++++ gcc/testsuite/gnat.dg/max_size_pkg.ads | 9 +++++++++ 6 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/max_size.adb create mode 100644 gcc/testsuite/gnat.dg/max_size_pkg.ads diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 9fa05898b2d..ba974cdcb03 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2018-12-14 Eric Botcazou + + * 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) : Likewise. + Do not subtract the padded size for Max_Size_In_Storage_Elements. + : Tweak comment. + 2018-12-14 Eric Botcazou * gcc-interface/decl.c (choices_to_gnu): Directly use a naked boolean diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 0ad06f1a9f1..df55f4893b7 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -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) diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 35b71ef838a..620dbd3d36d 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -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)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3cfdfaec305..4e0e910ebf1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-12-14 Eric Botcazou + + * gnat.dg/max_size.adb: New test. + * gnat.dg/max_size_pkg.ads: Likewise. + 2018-12-14 Claudiu Zissulescu * 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 index 00000000000..28562c16c01 --- /dev/null +++ b/gcc/testsuite/gnat.dg/max_size.adb @@ -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 index 00000000000..d4850c1bb49 --- /dev/null +++ b/gcc/testsuite/gnat.dg/max_size_pkg.ads @@ -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; -- 2.30.2