calls.c (expand_call): Do not use the target as the return slot if it is not sufficie...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 6 Oct 2014 17:30:34 +0000 (17:30 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 6 Oct 2014 17:30:34 +0000 (17:30 +0000)
* calls.c (expand_call): Do not use the target as the return slot if
it is not sufficiently aligned.

From-SVN: r215958

gcc/ChangeLog
gcc/calls.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/return4.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/return4_pkg.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/return4_pkg.ads [new file with mode: 0644]

index 13ac914d14bcf7c8e0c8c2933988723d2dfb87bf..73d5d5a6b92dd67eff39762b891bec122f13603a 100644 (file)
@@ -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
index 345331fa6db2f3b04d61fe26ad984d2c4f0547b2..9c19f38302a3e7b9fb59a3a2f2153ec9a4cae6af 100644 (file)
@@ -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
          {
index 99c66d9bbe2ec51941034db534286eee712a0fb1..2b54708db15a994d7b3691c84f5b4379f1e77624 100644 (file)
@@ -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 (file)
index 0000000..8202acf
--- /dev/null
@@ -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 (file)
index 0000000..0b59221
--- /dev/null
@@ -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 (file)
index 0000000..9ed220f
--- /dev/null
@@ -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;