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]

[tree-ssa] fix execute/20000917-1.c


The problem here is that I mis-read what we were doing for COMPOUND_EXPR,
and clobbered the TREE_TYPE of all statements of the STATEMENT_LIST.  

Most of the time, this didn't matter.  Except for calls.  If you zap the
type of a CALL_EXPR, then expand_call will fail to notice that the callee
returns an aggregate, and so fail to allocate a temporary to contain the
return value.

What happens at this point is ABI dependent.  On some targets we return
the struct in registers and everything's fine.  On other targets we use
an uninitialized pointer value and get random results.

The random bit meant that the test accidentally passed on i686, sometimes.
It did start failing on alpha-linux after the merge; I'm pretty sure it 
didn't fail before then, but I don't have old logs to prove it.

Anyway, the fix is fairly straightforward.  The preparation for an 
empty list is just defensive; I havn't actually seen that case.  I
would expect this to only happen after the front end generates an
error for user silliness.


r~


        * gimplify.c (voidify_wrapper_expr): Don't clobber TREE_TYPE of
        statements in a STATEMENT_LIST.  Be prepared for an empty list.

Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.112
diff -c -p -d -r1.1.2.112 gimplify.c
*** gimplify.c	13 Nov 2003 02:47:41 -0000	1.1.2.112
--- gimplify.c	14 Nov 2003 07:29:21 -0000
*************** voidify_wrapper_expr (tree wrapper)
*** 714,731 ****
  	  break;
  	}
  
!       /* Advance.  Set up the substatements appropriately for what we
! 	 will have when we're done.  */
        if (TREE_CODE (*p) == STATEMENT_LIST)
  	{
! 	  tree_stmt_iterator i;
! 	  for (i = tsi_start (*p); !tsi_one_before_end_p (i); tsi_next (&i))
! 	    {
! 	      tree t = tsi_stmt (i);
! 	      TREE_SIDE_EFFECTS (t) = 1;
! 	      TREE_TYPE (t) = void_type_node;
! 	    }
! 	  p = tsi_stmt_ptr (i);
  	}
        else
  	{ 
--- 714,724 ----
  	  break;
  	}
  
!       /* Advance to the last statement.  Set all container types to void.  */
        if (TREE_CODE (*p) == STATEMENT_LIST)
  	{
! 	  tree_stmt_iterator i = tsi_last (*p);
! 	  p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
  	}
        else
  	{ 
*************** voidify_wrapper_expr (tree wrapper)
*** 736,747 ****
  	    }
  	}
  
!       if (TREE_CODE (*p) == INIT_EXPR)
  	{
  	  /* The C++ frontend already did this for us.  */;
  	  temp = TREE_OPERAND (*p, 0);
  	}
!       else if (TREE_CODE (*p) == INDIRECT_REF)
  	{
  	  /* If we're returning a dereference, move the dereference outside
  	     the wrapper.  */
--- 729,740 ----
  	    }
  	}
  
!       if (p && TREE_CODE (*p) == INIT_EXPR)
  	{
  	  /* The C++ frontend already did this for us.  */;
  	  temp = TREE_OPERAND (*p, 0);
  	}
!       else if (p && TREE_CODE (*p) == INDIRECT_REF)
  	{
  	  /* If we're returning a dereference, move the dereference outside
  	     the wrapper.  */
*************** voidify_wrapper_expr (tree wrapper)
*** 756,762 ****
        else
  	{
  	  temp = create_tmp_var (TREE_TYPE (wrapper), "retval");
! 	  if (!IS_EMPTY_STMT (*p))
  	    {
  	      *p = build (MODIFY_EXPR, TREE_TYPE (temp), temp, *p);
  	      TREE_SIDE_EFFECTS (wrapper) = 1;
--- 749,755 ----
        else
  	{
  	  temp = create_tmp_var (TREE_TYPE (wrapper), "retval");
! 	  if (p && !IS_EMPTY_STMT (*p))
  	    {
  	      *p = build (MODIFY_EXPR, TREE_TYPE (temp), temp, *p);
  	      TREE_SIDE_EFFECTS (wrapper) = 1;


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