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]

Adjust when OP0 is copied to MEM for COMPONENT_REF


This handles an obscure case with ARRAY_RANGE_REF, currently used only
for Ada.  The test case is below and only fails on x86 with
-freg-struct-return.

Tested on i686-pc-linux-gnu.

procedure P2 is
   
   type BLK_T is new string (1..5);
   type DI_T is new string (1..8);
   
   function DI_Value return DI_T is
      V : DI_T;
   begin
      return V;
   end;
   
   B : BLK_T := BLK_T (DI_Value (1..5));

begin
   null;
end;

2003-07-13  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* expr.c (expand_expr, case COMPONENT_REF): If reg, copy OP0 to MEM
	both if OFFSET specified and if result BLKmode for ARRAY_RANGE_REF.

*** expr.c	9 Jul 2003 00:58:54 -0000	1.567
--- expr.c	13 Jul 2003 23:13:44 -0000
*************** expand_expr (tree exp, rtx target, enum 
*** 7441,7476 ****
  	  }
  
  	if (offset != 0)
  	  {
  	    rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
  					  EXPAND_SUM);
- 
- 	    /* If this object is in a register, put it into memory.
- 	       This case can't occur in C, but can in Ada if we have
- 	       unchecked conversion of an expression from a scalar type to
- 	       an array or record type.  */
- 	    if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
- 		|| GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF)
- 	      {
- 		/* If the operand is a SAVE_EXPR, we can deal with this by
- 		   forcing the SAVE_EXPR into memory.  */
- 		if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
- 		  {
- 		    put_var_into_stack (TREE_OPERAND (exp, 0),
- 					/*rescan=*/true);
- 		    op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
- 		  }
- 		else
- 		  {
- 		    tree nt
- 		      = build_qualified_type (TREE_TYPE (tem),
- 					      (TYPE_QUALS (TREE_TYPE (tem))
- 					       | TYPE_QUAL_CONST));
- 		    rtx memloc = assign_temp (nt, 1, 1, 1);
- 
- 		    emit_move_insn (memloc, op0);
- 		    op0 = memloc;
- 		  }
- 	      }
  
  	    if (GET_CODE (op0) != MEM)
--- 7441,7478 ----
  	  }
  
+  	/* Otherwise, if this object not in memory and we either have an
+  	   offset or a BLKmode result, put it there.  This case can't occur in
+  	   C, but can in Ada if we have unchecked conversion of an expression
+  	   from a scalar type to an array or record type or for an
+  	   ARRAY_RANGE_REF whose type is BLKmode.  */
+ 	else if (GET_CODE (op0) != MEM
+ 		 && (offset != 0
+ 		     || (code == ARRAY_RANGE_REF && mode == BLKmode)))
+ 	  {
+ 	    /* If the operand is a SAVE_EXPR, we can deal with this by
+ 	       forcing the SAVE_EXPR into memory.  */
+ 	    if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
+ 	      {
+ 		put_var_into_stack (TREE_OPERAND (exp, 0),
+ 				    /*rescan=*/true);
+ 		op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
+ 	      }
+ 	    else
+ 	      {
+ 		tree nt
+ 		  = build_qualified_type (TREE_TYPE (tem),
+ 					  (TYPE_QUALS (TREE_TYPE (tem))
+ 					   | TYPE_QUAL_CONST));
+ 		rtx memloc = assign_temp (nt, 1, 1, 1);
+ 		
+ 		emit_move_insn (memloc, op0);
+ 		op0 = memloc;
+ 	      }
+ 	  }
+ 
  	if (offset != 0)
  	  {
  	    rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
  					  EXPAND_SUM);
  
  	    if (GET_CODE (op0) != MEM)


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