aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2012-12-08 11:57:15 +0000
committerEric Botcazou <ebotcazou@adacore.com>2012-12-08 11:57:15 +0000
commit2af7312dee78e0e8c8c747b2175f1aa894bd3760 (patch)
treef1385a8610ac4efc56aa70d4c3ef83d6015783ca
parent5abbfe03c9e1badf35447efc7a408961155df69b (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@194321 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/gcc-interface/trans.c10
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/vect10.adb29
-rw-r--r--gcc/testsuite/gnat.dg/vect10.ads17
5 files changed, 63 insertions, 2 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 2898d2cb411..5a5834fc98e 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 291d00f1c27..f1398e2b6ba 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b150c598b70..b1f6c995bb1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
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.
* gnat.dg/vect9_pkg.ads: New helper.
diff --git a/gcc/testsuite/gnat.dg/vect10.adb b/gcc/testsuite/gnat.dg/vect10.adb
new file mode 100644
index 00000000000..819e2446d7a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/vect10.adb
@@ -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
index 00000000000..aa3aa343233
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/vect10.ads
@@ -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;