Commit c34f3839 by Eric Botcazou Committed by Eric Botcazou

trans.c (Identifier_to_gnu): Use boolean variable.

	* gcc-interface/trans.c (Identifier_to_gnu): Use boolean variable.
	(call_to_gnu): Test gigi's flag TYPE_BY_REFERENCE_P instead of calling
	front-end's predicate Is_By_Reference_Type.  Use consistent order and
	remove ??? comment.  Use original conversion in all cases, if any.
	* gcc-interface/utils.c (make_dummy_type): Minor tweak.
	(convert): Use local copy in more cases.
	<INDIRECT_REF>: Remove deactivated code.
	(unchecked_convert): Use a couple of local copies.

From-SVN: r158216
parent c4712597
2010-04-12 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (Identifier_to_gnu): Use boolean variable.
(call_to_gnu): Test gigi's flag TYPE_BY_REFERENCE_P instead of calling
front-end's predicate Is_By_Reference_Type. Use consistent order and
remove ??? comment. Use original conversion in all cases, if any.
* gcc-interface/utils.c (make_dummy_type): Minor tweak.
(convert): Use local copy in more cases.
<INDIRECT_REF>: Remove deactivated code.
(unchecked_convert): Use a couple of local copies.
2010-04-11 Eric Botcazou <ebotcazou@adacore.com> 2010-04-11 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (lvalue_required_for_attribute_p): New static * gcc-interface/trans.c (lvalue_required_for_attribute_p): New static
......
...@@ -997,18 +997,17 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) ...@@ -997,18 +997,17 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
&& DECL_P (gnu_result) && DECL_P (gnu_result)
&& DECL_INITIAL (gnu_result)) && DECL_INITIAL (gnu_result))
{ {
tree object bool constant_only = (TREE_CODE (gnu_result) == CONST_DECL
= (TREE_CODE (gnu_result) == CONST_DECL && !DECL_CONST_CORRESPONDING_VAR (gnu_result));
? DECL_CONST_CORRESPONDING_VAR (gnu_result) : gnu_result);
/* If there is a corresponding variable, we only want to return /* If there is a (corresponding) variable, we only want to return
the CST value if an lvalue is not required. Evaluate this the constant value if an lvalue is not required. Evaluate this
now if we have not already done so. */ now if we have not already done so. */
if (object && require_lvalue < 0) if (!constant_only && require_lvalue < 0)
require_lvalue = lvalue_required_p (gnat_node, gnu_result_type, true, require_lvalue = lvalue_required_p (gnat_node, gnu_result_type, true,
Is_Aliased (gnat_temp)); Is_Aliased (gnat_temp));
if (!object || !require_lvalue) if (constant_only || !require_lvalue)
gnu_result = unshare_expr (DECL_INITIAL (gnu_result)); gnu_result = unshare_expr (DECL_INITIAL (gnu_result));
} }
...@@ -2500,14 +2499,14 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target) ...@@ -2500,14 +2499,14 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
tree gnu_formal = present_gnu_tree (gnat_formal) tree gnu_formal = present_gnu_tree (gnat_formal)
? get_gnu_tree (gnat_formal) : NULL_TREE; ? get_gnu_tree (gnat_formal) : NULL_TREE;
tree gnu_formal_type = gnat_to_gnu_type (Etype (gnat_formal)); tree gnu_formal_type = gnat_to_gnu_type (Etype (gnat_formal));
/* We must suppress conversions that can cause the creation of a /* In the Out or In Out case, we must suppress conversions that yield
temporary in the Out or In Out case because we need the real an lvalue but can nevertheless cause the creation of a temporary,
object in this case, either to pass its address if it's passed because we need the real object in this case, either to pass its
by reference or as target of the back copy done after the call address if it's passed by reference or as target of the back copy
if it uses the copy-in copy-out mechanism. We do it in the In done after the call if it uses the copy-in copy-out mechanism.
case too, except for an unchecked conversion because it alone We do it in the In case too, except for an unchecked conversion
can cause the actual to be misaligned and the addressability because it alone can cause the actual to be misaligned and the
test is applied to the real object. */ addressability test is applied to the real object. */
bool suppress_type_conversion bool suppress_type_conversion
= ((Nkind (gnat_actual) == N_Unchecked_Type_Conversion = ((Nkind (gnat_actual) == N_Unchecked_Type_Conversion
&& Ekind (gnat_formal) != E_In_Parameter) && Ekind (gnat_formal) != E_In_Parameter)
...@@ -2539,8 +2538,9 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target) ...@@ -2539,8 +2538,9 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
{ {
tree gnu_copy = gnu_name; tree gnu_copy = gnu_name;
/* If the type is by_reference, a copy is not allowed. */ /* If the type is passed by reference, a copy is not allowed. */
if (Is_By_Reference_Type (Etype (gnat_formal))) if (AGGREGATE_TYPE_P (gnu_formal_type)
&& TYPE_BY_REFERENCE_P (gnu_formal_type))
post_error post_error
("misaligned actual cannot be passed by reference", gnat_actual); ("misaligned actual cannot be passed by reference", gnat_actual);
...@@ -2610,44 +2610,29 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target) ...@@ -2610,44 +2610,29 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
So do it here for the part we will use as an input, if any. */ So do it here for the part we will use as an input, if any. */
if (Ekind (gnat_formal) != E_Out_Parameter if (Ekind (gnat_formal) != E_Out_Parameter
&& TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual))) && TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual)))
gnu_actual = convert (get_unpadded_type (Etype (gnat_actual)), gnu_actual
gnu_actual); = convert (get_unpadded_type (Etype (gnat_actual)), gnu_actual);
/* Do any needed conversions for the actual and make sure that it is /* Put back the conversion we suppressed above in the computation of the
in range of the formal's type. */ real object. And even if we didn't suppress any conversion there, we
if (suppress_type_conversion) may have suppressed a conversion to the Etype of the actual earlier,
{ since the parent is a procedure call, so put it back here. */
/* Put back the conversion we suppressed above in the computation if (suppress_type_conversion
of the real object. Note that we treat a conversion between && Nkind (gnat_actual) == N_Unchecked_Type_Conversion)
aggregate types as if it is an unchecked conversion here. */
gnu_actual gnu_actual
= unchecked_convert (gnat_to_gnu_type (Etype (gnat_actual)), = unchecked_convert (gnat_to_gnu_type (Etype (gnat_actual)),
gnu_actual, gnu_actual, No_Truncation (gnat_actual));
(Nkind (gnat_actual)
== N_Unchecked_Type_Conversion)
&& No_Truncation (gnat_actual));
if (Ekind (gnat_formal) != E_Out_Parameter
&& Do_Range_Check (gnat_actual))
gnu_actual = emit_range_check (gnu_actual, Etype (gnat_formal),
gnat_actual);
}
else else
{ gnu_actual
= convert (gnat_to_gnu_type (Etype (gnat_actual)), gnu_actual);
/* Make sure that the actual is in range of the formal's type. */
if (Ekind (gnat_formal) != E_Out_Parameter if (Ekind (gnat_formal) != E_Out_Parameter
&& Do_Range_Check (gnat_actual)) && Do_Range_Check (gnat_actual))
gnu_actual = emit_range_check (gnu_actual, Etype (gnat_formal), gnu_actual
gnat_actual); = emit_range_check (gnu_actual, Etype (gnat_formal), gnat_actual);
/* We may have suppressed a conversion to the Etype of the actual
since the parent is a procedure call. So put it back here.
??? We use the reverse order compared to the case above because
of an awkward interaction with the check. */
if (TREE_CODE (gnu_actual) != SAVE_EXPR)
gnu_actual = convert (gnat_to_gnu_type (Etype (gnat_actual)),
gnu_actual);
}
/* And convert it to this type. */
if (TREE_CODE (gnu_actual) != SAVE_EXPR) if (TREE_CODE (gnu_actual) != SAVE_EXPR)
gnu_actual = convert (gnu_formal_type, gnu_actual); gnu_actual = convert (gnu_formal_type, gnu_actual);
...@@ -2657,8 +2642,8 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target) ...@@ -2657,8 +2642,8 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
&& TREE_CODE (gnu_name) == CONSTRUCTOR && TREE_CODE (gnu_name) == CONSTRUCTOR
&& TREE_CODE (TREE_TYPE (gnu_name)) == RECORD_TYPE && TREE_CODE (TREE_TYPE (gnu_name)) == RECORD_TYPE
&& TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (gnu_name))) && TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (gnu_name)))
gnu_name = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_name))), gnu_name
gnu_name); = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_name))), gnu_name);
/* If we have not saved a GCC object for the formal, it means it is an /* If we have not saved a GCC object for the formal, it means it is an
Out parameter not passed by reference and that need not be copied in. Out parameter not passed by reference and that need not be copied in.
......
...@@ -294,8 +294,8 @@ make_dummy_type (Entity_Id gnat_type) ...@@ -294,8 +294,8 @@ make_dummy_type (Entity_Id gnat_type)
TYPE_DUMMY_P (gnu_type) = 1; TYPE_DUMMY_P (gnu_type) = 1;
TYPE_STUB_DECL (gnu_type) TYPE_STUB_DECL (gnu_type)
= create_type_stub_decl (TYPE_NAME (gnu_type), gnu_type); = create_type_stub_decl (TYPE_NAME (gnu_type), gnu_type);
if (AGGREGATE_TYPE_P (gnu_type)) if (AGGREGATE_TYPE_P (gnu_type) && Is_By_Reference_Type (gnat_type))
TYPE_BY_REFERENCE_P (gnu_type) = Is_By_Reference_Type (gnat_type); TYPE_BY_REFERENCE_P (gnu_type) = 1;
SET_DUMMY_NODE (gnat_underlying, gnu_type); SET_DUMMY_NODE (gnat_underlying, gnu_type);
...@@ -3656,12 +3656,12 @@ convert_to_thin_pointer (tree type, tree expr) ...@@ -3656,12 +3656,12 @@ convert_to_thin_pointer (tree type, tree expr)
tree tree
convert (tree type, tree expr) convert (tree type, tree expr)
{ {
enum tree_code code = TREE_CODE (type);
tree etype = TREE_TYPE (expr); tree etype = TREE_TYPE (expr);
enum tree_code ecode = TREE_CODE (etype); enum tree_code ecode = TREE_CODE (etype);
enum tree_code code = TREE_CODE (type);
/* If EXPR is already the right type, we are done. */ /* If the expression is already of the right type, we are done. */
if (type == etype) if (etype == type)
return expr; return expr;
/* If both input and output have padding and are of variable size, do this /* If both input and output have padding and are of variable size, do this
...@@ -3708,7 +3708,7 @@ convert (tree type, tree expr) ...@@ -3708,7 +3708,7 @@ 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. But first pad the is a record, do this as an unchecked conversion. But first pad the
expression if possible to have the same size on both sides. */ expression if possible to have the same size on both sides. */
if (TREE_CODE (etype) == RECORD_TYPE if (ecode == RECORD_TYPE
&& CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type)))) && CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type))))
{ {
if (TREE_CONSTANT (TYPE_SIZE (etype))) if (TREE_CONSTANT (TYPE_SIZE (etype)))
...@@ -3721,7 +3721,7 @@ convert (tree type, tree expr) ...@@ -3721,7 +3721,7 @@ convert (tree type, tree expr)
final conversion as an unchecked conversion, again to avoid the need final conversion as an unchecked conversion, again to avoid the need
for some variable-sized temporaries. If valid, this conversion is for some variable-sized temporaries. If valid, this conversion is
very likely purely technical and without real effects. */ very likely purely technical and without real effects. */
if (TREE_CODE (etype) == ARRAY_TYPE if (ecode == ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == ARRAY_TYPE && TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == ARRAY_TYPE
&& !TREE_CONSTANT (TYPE_SIZE (etype)) && !TREE_CONSTANT (TYPE_SIZE (etype))
&& !TREE_CONSTANT (TYPE_SIZE (type))) && !TREE_CONSTANT (TYPE_SIZE (type)))
...@@ -4000,25 +4000,6 @@ convert (tree type, tree expr) ...@@ -4000,25 +4000,6 @@ convert (tree type, tree expr)
} }
break; break;
case INDIRECT_REF:
/* If both types are record types, just convert the pointer and
make a new INDIRECT_REF.
??? Disable this for now since it causes problems with the
code in build_binary_op for MODIFY_EXPR which wants to
strip off conversions. But that code really is a mess and
we need to do this a much better way some time. */
if (0
&& (TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE)
&& (TREE_CODE (etype) == RECORD_TYPE
|| TREE_CODE (etype) == UNION_TYPE)
&& !TYPE_IS_FAT_POINTER_P (type) && !TYPE_IS_FAT_POINTER_P (etype))
return build_unary_op (INDIRECT_REF, NULL_TREE,
convert (build_pointer_type (type),
TREE_OPERAND (expr, 0)));
break;
default: default:
break; break;
} }
...@@ -4359,29 +4340,26 @@ tree ...@@ -4359,29 +4340,26 @@ tree
unchecked_convert (tree type, tree expr, bool notrunc_p) unchecked_convert (tree type, tree expr, bool notrunc_p)
{ {
tree etype = TREE_TYPE (expr); tree etype = TREE_TYPE (expr);
enum tree_code ecode = TREE_CODE (etype);
enum tree_code code = TREE_CODE (type);
/* If the expression is already the right type, we are done. */ /* If the expression is already of the right type, we are done. */
if (etype == type) if (etype == type)
return expr; return expr;
/* If both types types are integral just do a normal conversion. /* If both types types are integral just do a normal conversion.
Likewise for a conversion to an unconstrained array. */ Likewise for a conversion to an unconstrained array. */
if ((((INTEGRAL_TYPE_P (type) if ((((INTEGRAL_TYPE_P (type)
&& !(TREE_CODE (type) == INTEGER_TYPE && !(code == INTEGER_TYPE && TYPE_VAX_FLOATING_POINT_P (type)))
&& TYPE_VAX_FLOATING_POINT_P (type)))
|| (POINTER_TYPE_P (type) && ! TYPE_IS_THIN_POINTER_P (type)) || (POINTER_TYPE_P (type) && ! TYPE_IS_THIN_POINTER_P (type))
|| (TREE_CODE (type) == RECORD_TYPE || (code == RECORD_TYPE && TYPE_JUSTIFIED_MODULAR_P (type)))
&& TYPE_JUSTIFIED_MODULAR_P (type)))
&& ((INTEGRAL_TYPE_P (etype) && ((INTEGRAL_TYPE_P (etype)
&& !(TREE_CODE (etype) == INTEGER_TYPE && !(ecode == INTEGER_TYPE && TYPE_VAX_FLOATING_POINT_P (etype)))
&& TYPE_VAX_FLOATING_POINT_P (etype)))
|| (POINTER_TYPE_P (etype) && !TYPE_IS_THIN_POINTER_P (etype)) || (POINTER_TYPE_P (etype) && !TYPE_IS_THIN_POINTER_P (etype))
|| (TREE_CODE (etype) == RECORD_TYPE || (ecode == RECORD_TYPE && TYPE_JUSTIFIED_MODULAR_P (etype))))
&& TYPE_JUSTIFIED_MODULAR_P (etype)))) || code == UNCONSTRAINED_ARRAY_TYPE)
|| TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
{ {
if (TREE_CODE (etype) == INTEGER_TYPE if (ecode == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (etype))
&& TYPE_BIASED_REPRESENTATION_P (etype))
{ {
tree ntype = copy_type (etype); tree ntype = copy_type (etype);
TYPE_BIASED_REPRESENTATION_P (ntype) = 0; TYPE_BIASED_REPRESENTATION_P (ntype) = 0;
...@@ -4389,8 +4367,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -4389,8 +4367,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
expr = build1 (NOP_EXPR, ntype, expr); expr = build1 (NOP_EXPR, ntype, expr);
} }
if (TREE_CODE (type) == INTEGER_TYPE if (code == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (type))
&& TYPE_BIASED_REPRESENTATION_P (type))
{ {
tree rtype = copy_type (type); tree rtype = copy_type (type);
TYPE_BIASED_REPRESENTATION_P (rtype) = 0; TYPE_BIASED_REPRESENTATION_P (rtype) = 0;
...@@ -4441,8 +4418,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -4441,8 +4418,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
/* We have a special case when we are converting between two unconstrained /* We have a special case when we are converting between two unconstrained
array types. In that case, take the address, convert the fat pointer array types. In that case, take the address, convert the fat pointer
types, and dereference. */ types, and dereference. */
else if (TREE_CODE (etype) == UNCONSTRAINED_ARRAY_TYPE else if (ecode == code && code == UNCONSTRAINED_ARRAY_TYPE)
&& TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
expr = build_unary_op (INDIRECT_REF, NULL_TREE, expr = build_unary_op (INDIRECT_REF, NULL_TREE,
build1 (VIEW_CONVERT_EXPR, TREE_TYPE (type), build1 (VIEW_CONVERT_EXPR, TREE_TYPE (type),
build_unary_op (ADDR_EXPR, NULL_TREE, build_unary_op (ADDR_EXPR, NULL_TREE,
...@@ -4450,8 +4426,8 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -4450,8 +4426,8 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
/* Another special case is when we are converting to a vector type from its /* Another special case is when we are converting to a vector type from its
representative array type; this a regular conversion. */ representative array type; this a regular conversion. */
else if (TREE_CODE (type) == VECTOR_TYPE else if (code == VECTOR_TYPE
&& TREE_CODE (etype) == ARRAY_TYPE && ecode == ARRAY_TYPE
&& gnat_types_compatible_p (TYPE_REPRESENTATIVE_ARRAY (type), && gnat_types_compatible_p (TYPE_REPRESENTATIVE_ARRAY (type),
etype)) etype))
expr = convert (type, expr); expr = convert (type, expr);
...@@ -4460,6 +4436,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -4460,6 +4436,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
{ {
expr = maybe_unconstrained_array (expr); expr = maybe_unconstrained_array (expr);
etype = TREE_TYPE (expr); etype = TREE_TYPE (expr);
ecode = TREE_CODE (etype);
if (can_fold_for_view_convert_p (expr)) if (can_fold_for_view_convert_p (expr))
expr = fold_build1 (VIEW_CONVERT_EXPR, type, expr); expr = fold_build1 (VIEW_CONVERT_EXPR, type, expr);
else else
...@@ -4472,8 +4449,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -4472,8 +4449,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
is a biased type or if both the input and output are unsigned. */ is a biased type or if both the input and output are unsigned. */
if (!notrunc_p if (!notrunc_p
&& INTEGRAL_TYPE_P (type) && TYPE_RM_SIZE (type) && INTEGRAL_TYPE_P (type) && TYPE_RM_SIZE (type)
&& !(TREE_CODE (type) == INTEGER_TYPE && !(code == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (type))
&& TYPE_BIASED_REPRESENTATION_P (type))
&& 0 != compare_tree_int (TYPE_RM_SIZE (type), && 0 != compare_tree_int (TYPE_RM_SIZE (type),
GET_MODE_BITSIZE (TYPE_MODE (type))) GET_MODE_BITSIZE (TYPE_MODE (type)))
&& !(INTEGRAL_TYPE_P (etype) && !(INTEGRAL_TYPE_P (etype)
...@@ -4484,8 +4460,8 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -4484,8 +4460,8 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
0)) 0))
&& !(TYPE_UNSIGNED (type) && TYPE_UNSIGNED (etype))) && !(TYPE_UNSIGNED (type) && TYPE_UNSIGNED (etype)))
{ {
tree base_type = gnat_type_for_mode (TYPE_MODE (type), tree base_type
TYPE_UNSIGNED (type)); = gnat_type_for_mode (TYPE_MODE (type), TYPE_UNSIGNED (type));
tree shift_expr tree shift_expr
= convert (base_type, = convert (base_type,
size_binop (MINUS_EXPR, size_binop (MINUS_EXPR,
......
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