This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix unaligned access in function returning composite type


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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]