Commit 6f2789da by Olivier Hainque Committed by Eric Botcazou

re PR ada/29025 (procedure doesn't modify In Out parameter)

	PR ada/29025
	* trans.c (gnat_gimplify_expr) <ADDR_EXPR>: When taking the address
	of a SAVE_EXPR, just make the operand addressable/not-readonly and
	let the common gimplifier code make and propagate a temporary copy.
	(call_to_gnu): Clarify the use of SAVE_EXPR for not addressable
	out/in-out actuals and defer setting the addressable/readonly bits
	to the gimplifier.

From-SVN: r116929
parent efaa616e
2006-09-13 Olivier Hainque <hainque@adacore.com>
PR ada/29025
* trans.c (gnat_gimplify_expr) <ADDR_EXPR>: When taking the address
of a SAVE_EXPR, just make the operand addressable/not-readonly and
let the common gimplifier code make and propagate a temporary copy.
(call_to_gnu): Clarify the use of SAVE_EXPR for not addressable
out/in-out actuals and defer setting the addressable/readonly bits
to the gimplifier.
2006-09-13 Eric Botcazou <ebotcazou@adacore.com> 2006-09-13 Eric Botcazou <ebotcazou@adacore.com>
PR ada/28591 PR ada/28591
......
...@@ -1775,18 +1775,12 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target) ...@@ -1775,18 +1775,12 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
&& (TYPE_JUSTIFIED_MODULAR_P (gnu_name_type))) && (TYPE_JUSTIFIED_MODULAR_P (gnu_name_type)))
gnu_name = convert (gnu_name_type, gnu_name); gnu_name = convert (gnu_name_type, gnu_name);
/* Make a SAVE_EXPR to both properly account for potential side
effects and handle the creation of a temporary copy. Special
code in gnat_gimplify_expr ensures that the same temporary is
used as the actual and copied back after the call. */
gnu_actual = save_expr (gnu_name); gnu_actual = save_expr (gnu_name);
/* Since we're going to take the address of the SAVE_EXPR, we
don't want it to be marked as unchanging. So set
TREE_ADDRESSABLE. */
gnu_temp = skip_simple_arithmetic (gnu_actual);
if (TREE_CODE (gnu_temp) == SAVE_EXPR)
{
TREE_ADDRESSABLE (gnu_temp) = 1;
TREE_READONLY (gnu_temp) = 0;
}
/* Set up to move the copy back to the original. */ /* Set up to move the copy back to the original. */
gnu_temp = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_temp = build_binary_op (MODIFY_EXPR, NULL_TREE,
gnu_copy, gnu_actual); gnu_copy, gnu_actual);
...@@ -4697,6 +4691,19 @@ gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) ...@@ -4697,6 +4691,19 @@ gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
return GS_ALL_DONE; return GS_ALL_DONE;
} }
/* If we are taking the address of a SAVE_EXPR, we are typically
processing a misaligned argument to be passed by reference in a
procedure call. We just mark the operand as addressable + not
readonly here and let the common gimplifier code perform the
temporary creation, initialization, and "instantiation" in place of
the SAVE_EXPR in further operands, in particular in the copy back
code inserted after the call. */
else if (TREE_CODE (op) == SAVE_EXPR)
{
TREE_ADDRESSABLE (op) = 1;
TREE_READONLY (op) = 0;
}
/* Otherwise, if we are taking the address of something that is neither /* Otherwise, if we are taking the address of something that is neither
reference, declaration, or constant, make a variable for the operand reference, declaration, or constant, make a variable for the operand
here and then take its address. If we don't do it this way, we may here and then take its address. If we don't do it this way, we may
......
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