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]

[Ada] Fix ICE on function call returning volatile record type


This is a regression present on the mainline: the compiler aborts on the access
to a component of the value returned by a function call, if the return type is 
a volatile record type that isn't controlled or tagged.

Tested on i586-suse-linux, applied on the mainline.


2012-02-15  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/trans.c (call_to_gnu): Create the temporary for the
	return value in the by-reference return type case if this isn't the
	expression of an object declaration.  Tidy up.


2012-02-15  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/volatile10.adb: New case.
	* gnat.dg/volatile10_pkg.ads: New helper.


-- 
Eric Botcazou
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 184256)
+++ gcc-interface/trans.c	(working copy)
@@ -3642,24 +3642,34 @@ call_to_gnu (Node_Id gnat_node, tree *gn
       went_into_elab_proc = true;
     }
 
-  /* First, create the temporary for the return value if we need it: for a
-     variable-sized return type if there is no target and this is not an
-     object declaration, or else there is a target and it is a slice or an
-     array with fixed size, as the gimplifier doesn't handle these cases;
-     otherwise for a function with copy-in/copy-out parameters if there is
-     no target, because we need to preserve the return value before copying
-     back the parameters.  This must be done before we push a binding level
-     around the call as we will pop it before copying the return value.  */
+  /* First, create the temporary for the return value when:
+
+       1. There is no target and the function has copy-in/copy-out parameters,
+	  because we need to preserve the return value before copying back the
+	  parameters.
+
+       2. There is no target and this is not an object declaration, and the
+	  return type is by-reference or has variable size, because in these
+	  cases the gimplifier cannot create the temporary.
+
+       3. There is a target and it is a slice or an array with fixed size,
+	  and the return type has variable size, because the gimplifier
+	  doesn't handle these cases.
+
+     This must be done before we push a binding level around the call, since
+     we will pop it before copying the return value.  */
   if (function_call
-      && ((TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST
-	   && ((!gnu_target
-		&& Nkind (Parent (gnat_node)) != N_Object_Declaration)
-	       || (gnu_target
-		   && (TREE_CODE (gnu_target) == ARRAY_RANGE_REF
-		       || (TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE
-			   && TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target)))
-			      == INTEGER_CST)))))
-	  || (!gnu_target && TYPE_CI_CO_LIST (gnu_subprog_type))))
+      && ((!gnu_target && TYPE_CI_CO_LIST (gnu_subprog_type))
+	  || (!gnu_target
+	      && Nkind (Parent (gnat_node)) != N_Object_Declaration
+	      && (TREE_ADDRESSABLE (gnu_result_type)
+		  || TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST))
+	  || (gnu_target
+	      && (TREE_CODE (gnu_target) == ARRAY_RANGE_REF
+		  || (TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE
+		      && TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target)))
+			 == INTEGER_CST))
+	      && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST)))
     gnu_retval = create_temporary ("R", gnu_result_type);
 
   /* Create the list of the actual parameters as GCC expects it, namely a
-- { dg-do compile }

with Volatile10_Pkg; use Volatile10_Pkg;

procedure Volatile10 is
   N : Num;
begin
   N := F.N1;
   N := F.N2;
end;
package Volatile10_Pkg is

   type Num is mod 2**9;

   type Rec is record
      B1  : Boolean;
      N1  : Num;
      B2  : Boolean;
      N2  : Num;
      B3  : Boolean;
      B4  : Boolean;
      B5  : Boolean;
      B6  : Boolean;
      B7  : Boolean;
      B8  : Boolean;
      B9  : Boolean;
      B10 : Boolean;
      B11 : Boolean;
      B12 : Boolean;
      B13 : Boolean;
      B14 : Boolean;
   end record;
   pragma Pack (Rec);
   for Rec'Size use 32;
   pragma Volatile(Rec);

   function F return Rec;

end Volatile10_Pkg;

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