aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2014-10-06 17:30:34 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2014-10-06 17:30:34 +0000
commit391756ad9de0df816b7bc1453969101b979a28fc (patch)
treeea06fd59a50b1ccf2853c4242c258315a40a2f8a
parent2a8ef767005baf7c026e42a4521673ad1a9320d1 (diff)
downloadgcc-391756ad9de0df816b7bc1453969101b979a28fc.zip
gcc-391756ad9de0df816b7bc1453969101b979a28fc.tar.gz
gcc-391756ad9de0df816b7bc1453969101b979a28fc.tar.bz2
calls.c (expand_call): Do not use the target as the return slot if it is not sufficiently aligned.
* calls.c (expand_call): Do not use the target as the return slot if it is not sufficiently aligned. From-SVN: r215958
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/calls.c9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/return4.adb22
-rw-r--r--gcc/testsuite/gnat.dg/return4_pkg.adb9
-rw-r--r--gcc/testsuite/gnat.dg/return4_pkg.ads9
6 files changed, 58 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 13ac914..73d5d5a6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-10-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * calls.c (expand_call): Do not use the target as the return slot if
+ it is not sufficiently aligned.
+
2014-10-06 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (analyze_swaps commentary): Add
diff --git a/gcc/calls.c b/gcc/calls.c
index 345331f..9c19f38 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2377,7 +2377,14 @@ expand_call (tree exp, rtx target, int ignore)
{
struct_value_size = int_size_in_bytes (rettype);
- if (target && MEM_P (target) && CALL_EXPR_RETURN_SLOT_OPT (exp))
+ /* Even if it is semantically safe to use the target as the return
+ slot, it may be not sufficiently aligned for the return type. */
+ if (CALL_EXPR_RETURN_SLOT_OPT (exp)
+ && target
+ && MEM_P (target)
+ && !(MEM_ALIGN (target) < TYPE_ALIGN (rettype)
+ && SLOW_UNALIGNED_ACCESS (TYPE_MODE (rettype),
+ MEM_ALIGN (target))))
structure_value_addr = XEXP (target, 0);
else
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 99c66d9..2b54708 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-10-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/return4.adb: New test.
+ * gnat.dg/return4_pkg.ad[sb]: New helper.
+
2014-10-06 Edward Smith-Rowland <3dw4rd@verizon.net>
* g++.dg/cpp1y/attr-deprecated-neg.C: Attribute no longer ignored.
diff --git a/gcc/testsuite/gnat.dg/return4.adb b/gcc/testsuite/gnat.dg/return4.adb
new file mode 100644
index 0000000..8202acf
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/return4.adb
@@ -0,0 +1,22 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+with Return4_Pkg; use Return4_Pkg;
+
+procedure Return4 is
+
+ type Local_Rec is record
+ C : Character;
+ R : Rec;
+ end record;
+ pragma Pack (Local_Rec);
+
+ L : Local_Rec;
+ for L'Alignment use 2;
+
+begin
+ L.R := Get_Value (0);
+ if L.R.I1 /= 0 then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/return4_pkg.adb b/gcc/testsuite/gnat.dg/return4_pkg.adb
new file mode 100644
index 0000000..0b59221
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/return4_pkg.adb
@@ -0,0 +1,9 @@
+package body Return4_Pkg is
+
+ function Get_Value (I : Integer) return Rec is
+ Value : Rec := (I1 => I, I2 => I, I3 => I);
+ begin
+ return Value;
+ end;
+
+end Return4_Pkg;
diff --git a/gcc/testsuite/gnat.dg/return4_pkg.ads b/gcc/testsuite/gnat.dg/return4_pkg.ads
new file mode 100644
index 0000000..9ed220f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/return4_pkg.ads
@@ -0,0 +1,9 @@
+package Return4_Pkg is
+
+ type Rec is record
+ I1, I2, I3 : Integer;
+ end record;
+
+ function Get_Value (I : Integer) return Rec;
+
+end Return4_Pkg;