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]

[3.3 PATCH] PR optimization/11059: Backport from mainline


The following patch is a backport to 3.3 from mainline of my fix for
PR optimization/11059, which is an ICE-on-valid when constructing
an empty union in C++.

The original patch:
http://gcc.gnu.org/ml/gcc-patches/2003-07/msg00464.html

was approved for mainline by Jim Wilson:
http://gcc.gnu.org/ml/gcc-patches/2003-07/msg00651.html

and has been on mainline for a week with any problems.


The following patch has been tested against the gcc-3_3-branch on
i686-pc-linux-gnu with a complete bootstrap, all languages except
treelang, and regression tested with a top-level "make -k check"
with no new failures.

Ok for the 3.3 branch?


2003-07-13  Roger Sayle  <roger@eyesopen.com>

	PR optimization/11059
	* expr.c (can_store_by_pieces): Return true if length is zero.
	(store_by_pieces): Do nothing if length is zero.
	(clear_by_pieces): Do nothing if length is zero.
	(clear_storage): Do nothing if length is zero.
	(store_constructor): Simplify code when size is zero, or the
	target has already been cleared.  This avoids emitting a
	blockage instruction when initializing empty structures.

	* g++.dg/opt/emptyunion.C: New testcase.


Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.498.2.18
diff -c -3 -p -r1.498.2.18 expr.c
*** expr.c	9 Jun 2003 03:28:23 -0000	1.498.2.18
--- expr.c	13 Jul 2003 13:32:53 -0000
*************** can_store_by_pieces (len, constfun, cons
*** 2659,2664 ****
--- 2659,2667 ----
    int reverse;
    rtx cst;

+   if (len == 0)
+     return 1;
+
    if (! MOVE_BY_PIECES_P (len, align))
      return 0;

*************** store_by_pieces (to, len, constfun, cons
*** 2734,2739 ****
--- 2737,2745 ----
  {
    struct store_by_pieces data;

+   if (len == 0)
+     return;
+
    if (! MOVE_BY_PIECES_P (len, align))
      abort ();
    to = protect_from_queue (to, 1);
*************** clear_by_pieces (to, len, align)
*** 2756,2761 ****
--- 2762,2770 ----
  {
    struct store_by_pieces data;

+   if (len == 0)
+     return;
+
    data.constfun = clear_by_pieces_1;
    data.constfundata = NULL;
    data.len = len;
*************** clear_storage (object, size)
*** 2926,2932 ****
        object = protect_from_queue (object, 1);
        size = protect_from_queue (size, 0);

!       if (GET_CODE (size) == CONST_INT
  	  && CLEAR_BY_PIECES_P (INTVAL (size), align))
  	clear_by_pieces (object, INTVAL (size), align);
        else if (clear_storage_via_clrstr (object, size, align))
--- 2935,2943 ----
        object = protect_from_queue (object, 1);
        size = protect_from_queue (size, 0);

!       if (GET_CODE (size) == CONST_INT && INTVAL (size) == 0)
! 	;
!       else if (GET_CODE (size) == CONST_INT
  	  && CLEAR_BY_PIECES_P (INTVAL (size), align))
  	clear_by_pieces (object, INTVAL (size), align);
        else if (clear_storage_via_clrstr (object, size, align))
*************** store_constructor (exp, target, cleared,
*** 4802,4812 ****
      {
        tree elt;

        /* We either clear the aggregate or indicate the value is dead.  */
!       if ((TREE_CODE (type) == UNION_TYPE
! 	   || TREE_CODE (type) == QUAL_UNION_TYPE)
! 	  && ! cleared
! 	  && ! CONSTRUCTOR_ELTS (exp))
  	/* If the constructor is empty, clear the union.  */
  	{
  	  clear_storage (target, expr_size (exp));
--- 4813,4825 ----
      {
        tree elt;

+       /* If size is zero or the target is already cleared, do nothing.  */
+       if (size == 0 || cleared)
+ 	cleared = 1;
        /* We either clear the aggregate or indicate the value is dead.  */
!       else if ((TREE_CODE (type) == UNION_TYPE
! 		|| TREE_CODE (type) == QUAL_UNION_TYPE)
! 	       && ! CONSTRUCTOR_ELTS (exp))
  	/* If the constructor is empty, clear the union.  */
  	{
  	  clear_storage (target, expr_size (exp));
*************** store_constructor (exp, target, cleared,
*** 4817,4823 ****
  	 set the initial value as zero so we can fold the value into
  	 a constant.  But if more than one register is involved,
  	 this probably loses.  */
!       else if (! cleared && GET_CODE (target) == REG && TREE_STATIC (exp)
  	       && GET_MODE_SIZE (GET_MODE (target)) <= UNITS_PER_WORD)
  	{
  	  emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
--- 4830,4836 ----
  	 set the initial value as zero so we can fold the value into
  	 a constant.  But if more than one register is involved,
  	 this probably loses.  */
!       else if (GET_CODE (target) == REG && TREE_STATIC (exp)
  	       && GET_MODE_SIZE (GET_MODE (target)) <= UNITS_PER_WORD)
  	{
  	  emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
*************** store_constructor (exp, target, cleared,
*** 4829,4838 ****
  	 clear the whole structure first.  Don't do this if TARGET is a
  	 register whose mode size isn't equal to SIZE since clear_storage
  	 can't handle this case.  */
!       else if (! cleared && size > 0
! 	       && ((list_length (CONSTRUCTOR_ELTS (exp))
! 		    != fields_length (type))
! 		   || mostly_zeros_p (exp))
  	       && (GET_CODE (target) != REG
  		   || ((HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target))
  		       == size)))
--- 4842,4849 ----
  	 clear the whole structure first.  Don't do this if TARGET is a
  	 register whose mode size isn't equal to SIZE since clear_storage
  	 can't handle this case.  */
!       else if (((list_length (CONSTRUCTOR_ELTS (exp)) != fields_length (type))
! 		|| mostly_zeros_p (exp))
  	       && (GET_CODE (target) != REG
  		   || ((HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target))
  		       == size)))


// PR optimization/11059
// This testcase ICEd because clear_by_pieces was called with zero length.
// { dg-do compile }
// { dg-options "-O2" }

union uni {};

int main() {
  uni *h;

  h = (uni *)new uni();
}

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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