From 824ae42bbaa43b8be6eb3b35bcbb64cd297170ba Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Wed, 15 Feb 2012 08:31:21 +0000 Subject: * gnat.dg/volatile10.adb: New case. * gnat.dg/volatile10_pkg.ads: New helper. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184257 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ada/gcc-interface/trans.c | 44 ++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'gcc/ada/gcc-interface/trans.c') diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 11478cbb676..e310004b216 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -3642,24 +3642,34 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, went_into_elab_proc = true; } - /* First, create the temporary for the return value if we need it: for a - 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. */ + /* First, create the temporary for the return value when: + + 1. There is no target and the function has copy-in/copy-out parameters, + because we need to preserve the return value before copying back the + parameters. + + 2. There is no target and this is not an object declaration, and the + return type is by-reference or has variable size, because in these + cases the gimplifier cannot create the temporary. + + 3. There is a target and it is a slice or an array with fixed size, + and the return type has variable size, because the gimplifier + doesn't handle these cases. + + This must be done before we push a binding level around the call, since + we will pop it before copying the return value. */ if (function_call - && ((TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST - && ((!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_target && TYPE_CI_CO_LIST (gnu_subprog_type)) + || (!gnu_target + && Nkind (Parent (gnat_node)) != N_Object_Declaration + && (TREE_ADDRESSABLE (gnu_result_type) + || TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST)) + || (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)) + && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST))) gnu_retval = create_temporary ("R", gnu_result_type); /* Create the list of the actual parameters as GCC expects it, namely a -- cgit v1.2.1