aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2012-02-15 08:31:21 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2012-02-15 08:31:21 +0000
commit4a582c9fda392a8218c427c60fe6378956de1831 (patch)
treeb228fa61c83988bd772d7a1ed811abf657a86589 /gcc
parent0f952eb4cc0fe7a0a7b0a60e093f8c1f6e13dd75 (diff)
downloadgcc-4a582c9fda392a8218c427c60fe6378956de1831.zip
gcc-4a582c9fda392a8218c427c60fe6378956de1831.tar.gz
gcc-4a582c9fda392a8218c427c60fe6378956de1831.tar.bz2
volatile10.adb: New case.
* gnat.dg/volatile10.adb: New case. * gnat.dg/volatile10_pkg.ads: New helper. From-SVN: r184257
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/gcc-interface/trans.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/volatile10.adb10
-rw-r--r--gcc/testsuite/gnat.dg/volatile10_pkg.ads29
5 files changed, 77 insertions, 17 deletions
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 <ebotcazou@adacore.com>
+
+ * 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 <gingold@adacore.com>
* 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 <ebotcazou@adacore.com>
+
+ * gnat.dg/volatile10.adb: New case.
+ * gnat.dg/volatile10_pkg.ads: New helper.
+
2012-02-14 Jason Merrill <jason@redhat.com>
* 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;