* gnat.dg/volatile10.adb: New case.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Feb 2012 08:31:21 +0000 (08:31 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Feb 2012 08:31:21 +0000 (08:31 +0000)
* 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
gcc/ada/gcc-interface/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/volatile10.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/volatile10_pkg.ads [new file with mode: 0644]

index 5b6372d..9b62238 100644 (file)
@@ -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).
index 11478cb..e310004 100644 (file)
@@ -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
index a7963aa..a90a6ae 100644 (file)
@@ -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 (file)
index 0000000..5f295b9
--- /dev/null
@@ -0,0 +1,10 @@
+-- { dg-do compile }\r
+\r
+with Volatile10_Pkg; use Volatile10_Pkg;\r
+\r
+procedure Volatile10 is\r
+   N : Num;\r
+begin\r
+   N := F.N1;\r
+   N := F.N2;\r
+end;\r
diff --git a/gcc/testsuite/gnat.dg/volatile10_pkg.ads b/gcc/testsuite/gnat.dg/volatile10_pkg.ads
new file mode 100644 (file)
index 0000000..3ad2a79
--- /dev/null
@@ -0,0 +1,29 @@
+package Volatile10_Pkg is\r
+\r
+   type Num is mod 2**9;\r
+\r
+   type Rec is record\r
+      B1  : Boolean;\r
+      N1  : Num;\r
+      B2  : Boolean;\r
+      N2  : Num;\r
+      B3  : Boolean;\r
+      B4  : Boolean;\r
+      B5  : Boolean;\r
+      B6  : Boolean;\r
+      B7  : Boolean;\r
+      B8  : Boolean;\r
+      B9  : Boolean;\r
+      B10 : Boolean;\r
+      B11 : Boolean;\r
+      B12 : Boolean;\r
+      B13 : Boolean;\r
+      B14 : Boolean;\r
+   end record;\r
+   pragma Pack (Rec);\r
+   for Rec'Size use 32;\r
+   pragma Volatile(Rec);\r
+\r
+   function F return Rec;\r
+\r
+end Volatile10_Pkg;\r