Commit 14cc7b26 by Eric Botcazou Committed by Eric Botcazou

trans.c (gnat_to_gnu): Minor tweak.

	* 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
parent 694b3bb3
2019-02-08 Eric Botcazou <ebotcazou@adacore.com> 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 * gcc-interface/utils.c (max_size) <tcc_unary>: Be prepared for an
operand with VOID_TYPE. operand with VOID_TYPE.
......
...@@ -7230,13 +7230,10 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -7230,13 +7230,10 @@ gnat_to_gnu (Node_Id gnat_node)
{ {
tree gnu_aggr_type; tree gnu_aggr_type;
/* ??? It is wrong to evaluate the type now, but there doesn't /* Check that this aggregate has not slipped through the cracks. */
seem to be any other practical way of doing it. */
gcc_assert (!Expansion_Delayed (gnat_node)); gcc_assert (!Expansion_Delayed (gnat_node));
gnu_aggr_type = gnu_result_type gnu_result_type = get_unpadded_type (Etype (gnat_node));
= get_unpadded_type (Etype (gnat_node));
if (TREE_CODE (gnu_result_type) == RECORD_TYPE if (TREE_CODE (gnu_result_type) == RECORD_TYPE
&& TYPE_CONTAINS_TEMPLATE_P (gnu_result_type)) && TYPE_CONTAINS_TEMPLATE_P (gnu_result_type))
...@@ -7244,6 +7241,8 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -7244,6 +7241,8 @@ gnat_to_gnu (Node_Id gnat_node)
= TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_result_type))); = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_result_type)));
else if (TREE_CODE (gnu_result_type) == VECTOR_TYPE) else if (TREE_CODE (gnu_result_type) == VECTOR_TYPE)
gnu_aggr_type = TYPE_REPRESENTATIVE_ARRAY (gnu_result_type); gnu_aggr_type = TYPE_REPRESENTATIVE_ARRAY (gnu_result_type);
else
gnu_aggr_type = gnu_result_type;
if (Null_Record_Present (gnat_node)) if (Null_Record_Present (gnat_node))
gnu_result = gnat_build_constructor (gnu_aggr_type, NULL); gnu_result = gnat_build_constructor (gnu_aggr_type, NULL);
......
...@@ -4356,19 +4356,12 @@ convert (tree type, tree expr) ...@@ -4356,19 +4356,12 @@ convert (tree type, tree expr)
/* If the inner type is of self-referential size and the expression type /* 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 is a record, do this as an unchecked conversion unless both types are
essentially the same. But first pad the expression if possible to essentially the same. */
have the same size on both sides. */
if (ecode == RECORD_TYPE if (ecode == RECORD_TYPE
&& CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type))) && CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type)))
&& TYPE_MAIN_VARIANT (etype) && TYPE_MAIN_VARIANT (etype)
!= TYPE_MAIN_VARIANT (TREE_TYPE (TYPE_FIELDS (type)))) != 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 /* If we are converting between array types with variable size, do the
final conversion as an unchecked conversion, again to avoid the need final conversion as an unchecked conversion, again to avoid the need
...@@ -4483,9 +4476,9 @@ convert (tree type, tree expr) ...@@ -4483,9 +4476,9 @@ convert (tree type, tree expr)
case STRING_CST: case STRING_CST:
/* If we are converting a STRING_CST to another constrained array type, /* If we are converting a STRING_CST to another constrained array type,
just make a new one in the proper type. */ just make a new one in the proper type. */
if (code == ecode && AGGREGATE_TYPE_P (etype) if (code == ecode
&& !(TREE_CODE (TYPE_SIZE (etype)) == INTEGER_CST && !(TREE_CONSTANT (TYPE_SIZE (etype))
&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)) && !TREE_CONSTANT (TYPE_SIZE (type))))
{ {
expr = copy_node (expr); expr = copy_node (expr);
TREE_TYPE (expr) = type; TREE_TYPE (expr) = type;
...@@ -5332,7 +5325,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -5332,7 +5325,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
so we skip all expressions that are references. */ so we skip all expressions that are references. */
else if (!REFERENCE_CLASS_P (expr) else if (!REFERENCE_CLASS_P (expr)
&& !AGGREGATE_TYPE_P (etype) && !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)))) && (c = tree_int_cst_compare (TYPE_SIZE (etype), TYPE_SIZE (type))))
{ {
if (c < 0) if (c < 0)
...@@ -5380,10 +5373,13 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -5380,10 +5373,13 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
return unchecked_convert (type, expr, notrunc_p); return unchecked_convert (type, expr, notrunc_p);
} }
/* If we are converting a CONSTRUCTOR to a more aligned RECORD_TYPE, bump /* If we are converting a CONSTRUCTOR to a more aligned aggregate type, bump
the alignment of the CONSTRUCTOR to speed up the copy operation. */ 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 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)) && TYPE_ALIGN (etype) < TYPE_ALIGN (type))
{ {
expr = convert (maybe_pad_type (etype, NULL_TREE, 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) ...@@ -5392,6 +5388,23 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
return unchecked_convert (type, expr, 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. */ /* Otherwise, just build a VIEW_CONVERT_EXPR of the expression. */
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment