This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix unaligned access in function returning composite type
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 06 Oct 2014 11:40:48 +0200
- Subject: [patch] Fix unaligned access in function returning composite type
- Authentication-results: sourceware.org; auth=none
Hi,
In Ada, we support all sorts of data structure layout, including on strict-
alignment targets, and the compiler must generate glue code if necessary.
The problem here is a function returning a structure by invisible reference
into a field which is not sufficient aligned because the enclosing object is
packed: in this case, the caller passes an address that is not correctly
aligned to the callee, which can result in an unaligned access in the callee.
Tested on x86_64-suse-linux and SPARC/Solaris, OK for the mainline.
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 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/return4.adb: New test.
* gnat.dg/return4_pkg.ad[sb]: New helper.
--
Eric Botcazou
Index: calls.c
===================================================================
--- calls.c (revision 215843)
+++ calls.c (working copy)
@@ -2377,7 +2377,14 @@ expand_call (tree exp, rtx target, int i
{
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
{
package Return4_Pkg is
type Rec is record
I1, I2, I3 : Integer;
end record;
function Get_Value (I : Integer) return Rec;
end Return4_Pkg;
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;
-- { 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;