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 assignment of array with Atomic_Components


This is a regression introduced by the new mechanism put in place to check 
that the middle-end doesn't create copies of by-ref types.  Which means that 
gigi is now responsible for creating temporaries when they are necessary.

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


2010-07-09  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/trans.c (gnat_gimplify_expr) <ADDR_EXPR>: Deal with
	CALL_EXPR.


2010-07-09  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/atomic3.adb: New test.


-- 
Eric Botcazou
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 161944)
+++ gcc-interface/trans.c	(working copy)
@@ -5988,33 +5988,31 @@ gnat_gimplify_expr (tree *expr_p, gimple
     case ADDR_EXPR:
       op = TREE_OPERAND (expr, 0);
 
-      if (TREE_CODE (op) == CONSTRUCTOR)
+      /* If we are taking the address of a constant CONSTRUCTOR, make sure it
+	 is put into static memory.  We know that it's going to be read-only
+	 given the semantics we have and it must be in static memory when the
+	 reference is in an elaboration procedure.  */
+      if (TREE_CODE (op) == CONSTRUCTOR && TREE_CONSTANT (op))
 	{
-	  /* If we are taking the address of a constant CONSTRUCTOR, make sure
-	     it is put into static memory.  We know it's going to be read-only
-	     given the semantics we have and it must be in static memory when
-	     the reference is in an elaboration procedure.  */
-	  if (TREE_CONSTANT (op))
-	    {
-	      tree addr = build_fold_addr_expr (tree_output_constant_def (op));
-	      *expr_p = fold_convert (TREE_TYPE (expr), addr);
-	    }
-
-	  /* Otherwise explicitly create the local temporary.  That's required
-	     if the type is passed by reference.  */
-	  else
-	    {
-	      tree mod, new_var = create_tmp_var_raw (TREE_TYPE (op), "C");
-	      TREE_ADDRESSABLE (new_var) = 1;
-	      gimple_add_tmp_var (new_var);
+	  tree addr = build_fold_addr_expr (tree_output_constant_def (op));
+	  *expr_p = fold_convert (TREE_TYPE (expr), addr);
+	  return GS_ALL_DONE;
+	}
 
-	      mod = build2 (INIT_EXPR, TREE_TYPE (new_var), new_var, op);
-	      gimplify_and_add (mod, pre_p);
+      /* Otherwise, if we are taking the address of a non-constant CONSTRUCTOR
+	 or of a call, explicitly create the local temporary.  That's required
+	 if the type is passed by reference.  */
+      if (TREE_CODE (op) == CONSTRUCTOR || TREE_CODE (op) == CALL_EXPR)
+	{
+	  tree mod, new_var = create_tmp_var_raw (TREE_TYPE (op), "C");
+	  TREE_ADDRESSABLE (new_var) = 1;
+	  gimple_add_tmp_var (new_var);
 
-	      TREE_OPERAND (expr, 0) = new_var;
-	      recompute_tree_invariant_for_addr_expr (expr);
-	    }
+	  mod = build2 (INIT_EXPR, TREE_TYPE (new_var), new_var, op);
+	  gimplify_and_add (mod, pre_p);
 
+	  TREE_OPERAND (expr, 0) = new_var;
+	  recompute_tree_invariant_for_addr_expr (expr);
 	  return GS_ALL_DONE;
 	}
 
-- { dg-do compile }

procedure Atomic3 is

   type Unsigned_32_T is mod 2 ** 32;
   for Unsigned_32_T'Size use 32;

   type Id_T is (One, Two, Three);

   type Array_T is array (Id_T) of Unsigned_32_T;
   pragma Atomic_Components (Array_T);

   A : Array_T := (others => 0);

   function Get_Array return Array_T is
   begin
      return A;
   end;

   X : Array_T;

begin
   X := Get_Array;
end;

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