diff options
Diffstat (limited to 'gcc/ada/gcc-interface')
| -rw-r--r-- | gcc/ada/gcc-interface/trans.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 580b492..01fdd49 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -3631,15 +3631,22 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, } /* First, create the temporary for the return value if we need it: for a - variable-sized return type if there is no target or if this is slice, - because the gimplifier doesn't support these cases; or for a function - with copy-in/copy-out parameters if there is no target, because we'll - need to preserve the return value before copying back the parameters. - This must be done before we push a new binding level around the call - as we will pop it before copying the return value. */ + variable-sized return type if there is no target and this is not an + object declaration, or else there is a target and it is a slice or an + array with fixed size, as the gimplifier doesn't handle these cases; + otherwise for a function with copy-in/copy-out parameters if there is + no target, because we need to preserve the return value before copying + back the parameters. This must be done before we push a binding level + around the call as we will pop it before copying the return value. */ if (function_call && ((TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST - && (!gnu_target || TREE_CODE (gnu_target) == ARRAY_RANGE_REF)) + && ((!gnu_target + && Nkind (Parent (gnat_node)) != N_Object_Declaration) + || (gnu_target + && (TREE_CODE (gnu_target) == ARRAY_RANGE_REF + || (TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE + && TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target))) + == INTEGER_CST))))) || (!gnu_target && TYPE_CI_CO_LIST (gnu_subprog_type)))) gnu_retval = create_temporary ("R", gnu_result_type); |
