From 967e627adc2763b193ba68769eb4e7da2a7b8b55 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 19 Nov 2000 00:36:18 -0800 Subject: [PATCH] c-decl.c (grokdeclarator): Special case the creation of an index for a zero-length array. * 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. From-SVN: r37558 --- gcc/ChangeLog | 6 ++++++ gcc/c-decl.c | 50 ++++++++++++++++++++++++++++++++------------------ gcc/tree.c | 21 +++------------------ 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59c5f77e761..1e26641cb43 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2000-11-18 Richard Henderson + + * 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. + 2000-11-18 Marek Michalkiewicz * config/avr/avr-protos.h (avr_output_addr_vec_elt): Prototype. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index d97419d2e99..8868a11b39e 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -4494,27 +4494,41 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) } } - /* 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)) + if (integer_zerop (size)) { - error ("size of array `%s' is too large", name); - type = error_mark_node; - continue; + /* 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 (size_varies) - itype = variable_size (itype); - itype = build_index_type (itype); + /* 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 diff --git a/gcc/tree.c b/gcc/tree.c index b0a1ae18759..7652052662e 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -3676,33 +3676,18 @@ build_index_type (maxval) 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_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)) + if (host_integerp (maxval, 1)) return type_hash_canon (tree_low_cst (maxval, 1), itype); else return itype;