This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Somewhat-related changes to expr.c & tree.c
- To: Richard Kenner <kenner at vlsi1 dot ultra dot nyu dot edu>
- Subject: Re: Somewhat-related changes to expr.c & tree.c
- From: Richard Henderson <rth at redhat dot com>
- Date: Sat, 18 Nov 2000 14:48:22 -0800
- Cc: gcc-patches at gcc dot gnu dot org, mark at codesourcery dot com
- References: <10010202115.AA04986@vlsi1.ultra.nyu.edu>
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;