trans.c (Subprogram_Body_to_gnu): Be prepared for a by-ref VAR_DECL in the case of...
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 8 Dec 2012 11:57:15 +0000 (11:57 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 8 Dec 2012 11:57:15 +0000 (11:57 +0000)
* gcc-interface/trans.c (Subprogram_Body_to_gnu): Be prepared for a
by-ref VAR_DECL in the case of an Out parameter passed by copy.

From-SVN: r194321

gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/vect10.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/vect10.ads [new file with mode: 0644]

index 2898d2cb4113f6c11eb0de20b91da66c228f3a09..5a5834fc98e3d5cf255cd01c1cc04ab8c1a440b2 100644 (file)
@@ -1,3 +1,8 @@
+2012-12-08  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/trans.c (Subprogram_Body_to_gnu): Be prepared for a
+       by-ref VAR_DECL in the case of an Out parameter passed by copy.
+
 2012-12-05  Robert Dewar  <dewar@adacore.com>
 
        * par_sco.adb, sem_prag.adb, put_scos.adb, get_scos.adb: Minor
index 291d00f1c275193dd1190d768e20f96afcbdeb6a..f1398e2b6ba452bf3b5bfa39fccc282ccd9d9b77 100644 (file)
@@ -3375,16 +3375,22 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
        if (!present_gnu_tree (gnat_param))
          {
            tree gnu_cico_entry = gnu_cico_list;
+           tree gnu_decl;
 
            /* Skip any entries that have been already filled in; they must
               correspond to In Out parameters.  */
            while (gnu_cico_entry && TREE_VALUE (gnu_cico_entry))
              gnu_cico_entry = TREE_CHAIN (gnu_cico_entry);
 
+           /* Do any needed dereferences for by-ref objects.  */
+           gnu_decl = gnat_to_gnu_entity (gnat_param, NULL_TREE, 1);
+           gcc_assert (DECL_P (gnu_decl));
+           if (DECL_BY_REF_P (gnu_decl))
+             gnu_decl = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_decl);
+
            /* Do any needed references for padded types.  */
            TREE_VALUE (gnu_cico_entry)
-             = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_entry)),
-                        gnat_to_gnu_entity (gnat_param, NULL_TREE, 1));
+             = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_entry)), gnu_decl);
          }
     }
   else
index b150c598b701b97c06e64f601b8680bf8909075d..b1f6c995bb11b9bd6fc5fa1e218078f2a0dd63e9 100644 (file)
@@ -1,3 +1,7 @@
+2012-12-08  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/vect10.ad[sb]: New test.
+
 2012-12-08  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/vect9.ad[sb]: New test.
diff --git a/gcc/testsuite/gnat.dg/vect10.adb b/gcc/testsuite/gnat.dg/vect10.adb
new file mode 100644 (file)
index 0000000..819e244
--- /dev/null
@@ -0,0 +1,29 @@
+-- { dg-do compile }
+
+package body Vect10 is
+
+   procedure Add_Mul (X : in out Unit; Y, Z : in Unit) is
+   begin
+       X := X + Y * Z;
+   end;
+   pragma Inline_Always (Add_Mul);
+
+   procedure Proc
+     (F           : in Rec_Vector;
+      First_Index : in Natural;
+      Last_Index  : in Natural;
+      Result      : out Unit)
+   is
+   begin
+      Result := (others => 0.0);
+
+      for I in First_Index + 1 .. Last_Index loop
+         declare
+            Local : Rec renames F (I);
+         begin
+            Add_Mul (Result, Local.Val, Local.Val);
+         end;
+      end loop;
+   end;
+
+end Vect10;
diff --git a/gcc/testsuite/gnat.dg/vect10.ads b/gcc/testsuite/gnat.dg/vect10.ads
new file mode 100644 (file)
index 0000000..aa3aa34
--- /dev/null
@@ -0,0 +1,17 @@
+with Vect9_Pkg; use Vect9_Pkg;
+
+package Vect10 is
+
+   type Rec is record
+      Val : Unit;
+   end record;
+
+   type Rec_Vector is array (Positive range <>) of Rec;
+
+   procedure Proc
+     (F            : in Rec_Vector;
+      First_Index : in Natural;
+      Last_Index  : in Natural;
+      Result      : out Unit);
+
+end Vect10;