From 824ae42bbaa43b8be6eb3b35bcbb64cd297170ba Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Wed, 15 Feb 2012 08:31:21 +0000 Subject: [PATCH] * 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/ChangeLog | 6 +++++ gcc/ada/gcc-interface/trans.c | 44 ++++++++++++++++++++------------ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gnat.dg/volatile10.adb | 10 ++++++++ gcc/testsuite/gnat.dg/volatile10_pkg.ads | 29 +++++++++++++++++++++ 5 files changed, 77 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/volatile10.adb create mode 100644 gcc/testsuite/gnat.dg/volatile10_pkg.ads diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 5b6372d..9b62238 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2012-02-15 Eric Botcazou + + * gcc-interface/trans.c (call_to_gnu): Create the temporary for the + return value in the by-reference return type case if this isn't the + expression of an object declaration.  Tidy up. + 2012-02-09 Tristan Gingold * gcc-interface/Makefile.in: Remove .sym rule (not used). diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 11478cb..e310004 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a7963aa..a90a6ae 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-02-15 Eric Botcazou + + * gnat.dg/volatile10.adb: New case. + * gnat.dg/volatile10_pkg.ads: New helper. + 2012-02-14 Jason Merrill * g++.dg/ext/attrib43.C: New. diff --git a/gcc/testsuite/gnat.dg/volatile10.adb b/gcc/testsuite/gnat.dg/volatile10.adb new file mode 100644 index 0000000..5f295b9 --- /dev/null +++ b/gcc/testsuite/gnat.dg/volatile10.adb @@ -0,0 +1,10 @@ +-- { dg-do compile } + +with Volatile10_Pkg; use Volatile10_Pkg; + +procedure Volatile10 is + N : Num; +begin + N := F.N1; + N := F.N2; +end; diff --git a/gcc/testsuite/gnat.dg/volatile10_pkg.ads b/gcc/testsuite/gnat.dg/volatile10_pkg.ads new file mode 100644 index 0000000..3ad2a79 --- /dev/null +++ b/gcc/testsuite/gnat.dg/volatile10_pkg.ads @@ -0,0 +1,29 @@ +package Volatile10_Pkg is + + type Num is mod 2**9; + + type Rec is record + B1 : Boolean; + N1 : Num; + B2 : Boolean; + N2 : Num; + B3 : Boolean; + B4 : Boolean; + B5 : Boolean; + B6 : Boolean; + B7 : Boolean; + B8 : Boolean; + B9 : Boolean; + B10 : Boolean; + B11 : Boolean; + B12 : Boolean; + B13 : Boolean; + B14 : Boolean; + end record; + pragma Pack (Rec); + for Rec'Size use 32; + pragma Volatile(Rec); + + function F return Rec; + +end Volatile10_Pkg; -- 2.7.4