From: Eric Botcazou Date: Fri, 8 Feb 2019 11:37:40 +0000 (+0000) Subject: trans.c (gnat_to_gnu): Minor tweak. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=14cc7b26a9c3596bbe0d13fafa1917d89aa6f7e4;p=gcc.git trans.c (gnat_to_gnu): Minor tweak. * gcc-interface/trans.c (gnat_to_gnu) : 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 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b120650cda8..9003beccace 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2019-02-08 Eric Botcazou + + * gcc-interface/trans.c (gnat_to_gnu) : 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 * gcc-interface/utils.c (max_size) : Be prepared for an diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 71b626b291f..155cb4b27ab 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -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); diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 65b7e0f3cac..da4e1009e8c 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -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 {