aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2000-11-19 00:36:18 -0800
committerRichard Henderson <rth@gcc.gnu.org>2000-11-19 00:36:18 -0800
commit967e627adc2763b193ba68769eb4e7da2a7b8b55 (patch)
tree968eb2abfe36e88e8e6ebef7becc08a93f529686 /gcc
parente9284adfd06bd4f01bdc8fa4f708d3b9850e82d2 (diff)
downloadgcc-967e627adc2763b193ba68769eb4e7da2a7b8b55.zip
gcc-967e627adc2763b193ba68769eb4e7da2a7b8b55.tar.gz
gcc-967e627adc2763b193ba68769eb4e7da2a7b8b55.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-decl.c50
-rw-r--r--gcc/tree.c21
3 files changed, 41 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 59c5f77..1e26641 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2000-11-18 Richard Henderson <rth@redhat.com>
+
+ * 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 <marekm@linux.org.pl>
* config/avr/avr-protos.h (avr_output_addr_vec_elt): Prototype.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index d97419d..8868a11 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 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 (size_varies)
+ itype = variable_size (itype);
+ itype = build_index_type (itype);
+ }
}
#if 0
diff --git a/gcc/tree.c b/gcc/tree.c
index b0a1ae1..7652052 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;