* c-decl.c (grokdeclarator): Special case the creation of an
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Nov 2000 08:36:18 +0000 (08:36 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Nov 2000 08:36:18 +0000 (08:36 +0000)
        index for a zero-length array.
        * tree.c (build_index_type): Revert Oct 20 change.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37558 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-decl.c
gcc/tree.c

index 59c5f77..1e26641 100644 (file)
@@ -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.
index d97419d..8868a11 100644 (file)
@@ -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
index b0a1ae1..7652052 100644 (file)
@@ -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;