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]

Re: Somewhat-related changes to expr.c & tree.c


On Fri, Oct 20, 2000 at 06:01:52PM -0400, Richard Kenner wrote:
> Most of the other changes are things that fall out from that, except
> for the change to build_index_type which avoid overflow problems for
> zero-length arrays (and should have been in that patch but I forgot
> about it then).
> 
> Fri Oct 20 17:05:49 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
[...]
> 	(build_index_type): If upper bound is a negative number, lower
> 	bound is zero and sizetype is unsigned, use upper bound of one and
> 	lower of zero.

This change broke zero-length arrays, as shown in execute/zerolen-1.c.

First, the change didn't do what is described in the ChangeLog -- you
actually made the _lower_ bound one, and the _upper_ bound zero.

I can see what you are trying to do: make MAX-MIN == -1 so that the 
total size of the array still comes out to zero.  But this messes up
get_inner_reference, since array[0] is now "before" the start of the
array.

I think the basic problem here is that a zero-based, zero-length array
is not actually representable given an unsigned index type, so we 
shouldn't try.

The following executes the two zerolen tests correcty.  I've not checked
to see whether the C++ front end needs similar treatment, but I suspect
it does.  Alternately, we could change the special-case logic in
build_index_type to special case this properly, but that seems sorta fishy.

Opinions?


r~


	* c-decl.c (grokdeclarator): Special case the creation of an
	index for a zero-length array.
	* tree.c (build_index_type): Revert Oct 20 change.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-decl.c,v
retrieving revision 1.177
diff -c -p -d -r1.177 c-decl.c
*** c-decl.c	2000/11/17 06:05:13	1.177
--- c-decl.c	2000/11/18 22:37:24
*************** grokdeclarator (declarator, declspecs, d
*** 4494,4520 ****
  		    }
  		}
  
! 	      /* Convert size to index_type, so that if it is a variable
! 		 the computations will be done in the proper mode.  */
! 	      itype = fold (build (MINUS_EXPR, index_type,
! 				   convert (index_type, size),
! 				   convert (index_type, size_one_node)));
! 
! 	      /* If that overflowed, the array is too big.
! 		 ??? While a size of INT_MAX+1 technically shouldn't cause
! 		 an overflow (because we subtract 1), the overflow is recorded
! 		 during the conversion to index_type, before the subtraction.
! 		 Handling this case seems like an unnecessary complication.  */
! 	      if (TREE_OVERFLOW (itype))
  		{
! 		  error ("size of array `%s' is too large", name);
! 		  type = error_mark_node;
! 		  continue;
  		}
  
! 	      if (size_varies)
! 		itype = variable_size (itype);
! 	      itype = build_index_type (itype);
  	    }
  
  #if 0
--- 4494,4534 ----
  		    }
  		}
  
! 	      if (integer_zerop (size))
  		{
! 		  /* A zero-length array cannot be represented with an
! 		     unsigned index type, which is what we'll get with
! 		     build_index_type.  Create a signed range instead.  */
! 		  itype = build_range_type (index_type, size,
! 					    build_int_2 (-1, -1));
  		}
+ 	      else
+ 		{
+ 		  /* Compute the maximum valid index, that is, size - 1.
+ 		     Do the calculation in index_type, so that if it is
+ 		     a variable the computations will be done in the
+ 		     proper mode.  */
+ 	          itype = fold (build (MINUS_EXPR, index_type,
+ 				       convert (index_type, size),
+ 				       convert (index_type, size_one_node)));
  
! 	          /* If that overflowed, the array is too big.
! 		     ??? While a size of INT_MAX+1 technically shouldn't
! 		     cause an overflow (because we subtract 1), the overflow
! 		     is recorded during the conversion to index_type, before
! 		     the subtraction.  Handling this case seems like an
! 		     unnecessary complication.  */
! 		  if (TREE_OVERFLOW (itype))
! 		    {
! 		      error ("size of array `%s' is too large", name);
! 		      type = error_mark_node;
! 		      continue;
! 		    }
! 
! 		  if (size_varies)
! 		    itype = variable_size (itype);
! 		  itype = build_index_type (itype);
! 		}
  	    }
  
  #if 0
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.173
diff -c -p -d -r1.173 tree.c
*** tree.c	2000/11/17 17:31:08	1.173
--- tree.c	2000/11/18 22:37:24
*************** build_index_type (maxval)
*** 3676,3708 ****
       tree maxval;
  {
    register tree itype = make_node (INTEGER_TYPE);
-   int no_hash = 0;
  
    TREE_TYPE (itype) = sizetype;
    TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
! 
!   /* If sizetype is unsigned and the upper bound is negative, use a
!      lower bound of one and an upper bound of zero.  */
!   if (TREE_UNSIGNED (sizetype) && TREE_CODE (maxval) == INTEGER_CST
!       && tree_int_cst_sgn (maxval) < 0)
!     {
!       TYPE_MIN_VALUE (itype) = size_one_node;
!       TYPE_MAX_VALUE (itype) = size_zero_node;
!       no_hash = 1;
!     }
!   else
!     {
!       TYPE_MIN_VALUE (itype) = size_zero_node;
!       TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
!     }
! 
    TYPE_MODE (itype) = TYPE_MODE (sizetype);
    TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
    TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype);
    TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
    TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (sizetype);
  
!   if (!no_hash && host_integerp (maxval, 1))
      return type_hash_canon (tree_low_cst (maxval, 1), itype);
    else
      return itype;
--- 3676,3693 ----
       tree maxval;
  {
    register tree itype = make_node (INTEGER_TYPE);
  
    TREE_TYPE (itype) = sizetype;
    TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
!   TYPE_MIN_VALUE (itype) = size_zero_node;
!   TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
    TYPE_MODE (itype) = TYPE_MODE (sizetype);
    TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
    TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype);
    TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
    TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (sizetype);
  
!   if (host_integerp (maxval, 1))
      return type_hash_canon (tree_low_cst (maxval, 1), itype);
    else
      return itype;

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