diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2013-11-18 10:09:10 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2013-11-18 10:09:10 +0000 |
commit | 96540b24aa7048d4044d66e8a4225f769a72d65e (patch) | |
tree | 63dace76d2dab828da63661f1b501a26fced05ba /gcc/ada/gcc-interface/trans.c | |
parent | 9adcf5b40abb931351d356213eee9e6f79865128 (diff) | |
download | gcc-96540b24aa7048d4044d66e8a4225f769a72d65e.zip gcc-96540b24aa7048d4044d66e8a4225f769a72d65e.tar.gz gcc-96540b24aa7048d4044d66e8a4225f769a72d65e.tar.bz2 |
trans.c (Call_to_gnu): For an Out parameter passed by copy and that don't need to be copied in...
* gcc-interface/trans.c (Call_to_gnu): For an Out parameter passed by
copy and that don't need to be copied in, only evaluate its address.
From-SVN: r204943
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index b6a8be8..cbfb7e7 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -4130,9 +4130,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, 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 - Out parameter not passed by reference and that need not be copied in. - Otherwise, first see if the parameter is passed by reference. */ + /* First see if the parameter is passed by reference. */ if (is_true_formal_parm && DECL_BY_REF_P (gnu_formal)) { if (Ekind (gnat_formal) != E_In_Parameter) @@ -4178,6 +4176,9 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, gnu_formal_type = TREE_TYPE (gnu_formal); gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual); } + + /* Then see if the parameter is an array passed to a foreign convention + subprogram. */ else if (is_true_formal_parm && DECL_BY_COMPONENT_PTR_P (gnu_formal)) { gnu_formal_type = TREE_TYPE (gnu_formal); @@ -4198,6 +4199,8 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, but this is the most likely to work in all cases. */ gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual); } + + /* Then see if the parameter is passed by descriptor. */ else if (is_true_formal_parm && DECL_BY_DESCRIPTOR_P (gnu_formal)) { gnu_actual = convert (gnu_formal_type, gnu_actual); @@ -4214,6 +4217,8 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, (TREE_TYPE (TREE_TYPE (gnu_formal)), gnu_actual, gnat_actual)); } + + /* Otherwise the parameter is passed by copy. */ else { tree gnu_size; @@ -4221,11 +4226,18 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, if (Ekind (gnat_formal) != E_In_Parameter) gnu_name_list = tree_cons (NULL_TREE, gnu_name, gnu_name_list); + /* If we didn't create a PARM_DECL for the formal, this means that + it is an Out parameter not passed by reference and that need not + be copied in. In this case, the value of the actual need not be + read. However, we still need to make sure that its side-effects + are evaluated before the call, so we evaluate its address. */ if (!is_true_formal_parm) { - /* Make sure side-effects are evaluated before the call. */ if (TREE_SIDE_EFFECTS (gnu_name)) - append_to_statement_list (gnu_name, &gnu_stmt_list); + { + tree addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_name); + append_to_statement_list (addr, &gnu_stmt_list); + } continue; } |