]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree.c (valid_constant_size_p): New function.
authorRichard Guenther <rguenther@suse.de>
Wed, 2 May 2012 11:22:31 +0000 (11:22 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 2 May 2012 11:22:31 +0000 (11:22 +0000)
2012-05-02  Richard Guenther  <rguenther@suse.de>

* tree.c (valid_constant_size_p): New function.
* tree.h (valid_constant_size_p): Declare.
* cfgexpand.c (expand_one_var): Adjust check for too large
variables by using valid_constant_size_p.
* varasm.c (assemble_variable): Likewise.

c/
* c-decl.c (grokdeclarator): Properly check for sizes that
cover more than half of the address-space.

cp/
* decl.c (grokdeclarator): Properly check for sizes that
cover more than half of the address-space.

2012-05-02  Richard Guenther  <rguenther@suse.de>

* fold-const.c (div_if_zero_remainder): sizetypes no longer
sign-extend.
(int_const_binop_1): New worker for int_const_binop with
overflowable parameter.  Pass it through
to force_fit_type_double.
(int_const_binop): Wrap around int_const_binop_1 with overflowable
equal to one.
(size_binop_loc): Call int_const_binop_1 with overflowable equal
to minus one, forcing overflow detection for even unsigned types.
(extract_muldiv_1): Remove bogus TYPE_IS_SIZETYPE special-casing.
(fold_binary_loc): Call try_move_mult_to_index with signed offset.
* stor-layout.c (initialize_sizetypes): sizetypes no longer
sign-extend.
(layout_type): For zero-sized arrays ignore overflow on the
size calculations.
* tree-ssa-ccp.c (bit_value_unop_1): Likewise.
(bit_value_binop_1): Likewise.
* tree.c (double_int_to_tree): Likewise.
(double_int_fits_to_tree_p): Likewise.
(force_fit_type_double): Likewise.
(host_integerp): Likewise.
(int_fits_type_p): Likewise.
* varasm.c (output_constructor_regular_field): Sign-extend the
field-offset to cater for negative offsets produced by the Ada frontend.
* omp-low.c (extract_omp_for_data): Convert the loop step to
signed for pointer adjustments.

* g++.dg/tree-ssa/pr19807.C: Adjust.

From-SVN: r187042

14 files changed:
gcc/ChangeLog
gcc/c-decl.c
gcc/cfgexpand.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/fold-const.c
gcc/omp-low.c
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr19807.C
gcc/tree-ssa-ccp.c
gcc/tree.c
gcc/tree.h
gcc/varasm.c

index f9b8a6e84f260e14d65d5ac6a9de07f9201a7f82..485395915600259e63c08a1e42af173003aa7bbe 100644 (file)
@@ -1,3 +1,43 @@
+2012-05-02  Richard Guenther  <rguenther@suse.de>
+
+       * fold-const.c (div_if_zero_remainder): sizetypes no longer
+       sign-extend.
+       (int_const_binop_1): New worker for int_const_binop with
+       overflowable parameter.  Pass it through
+       to force_fit_type_double.
+       (int_const_binop): Wrap around int_const_binop_1 with overflowable
+       equal to one.
+       (size_binop_loc): Call int_const_binop_1 with overflowable equal
+       to minus one, forcing overflow detection for even unsigned types.
+       (extract_muldiv_1): Remove bogus TYPE_IS_SIZETYPE special-casing.
+       (fold_binary_loc): Call try_move_mult_to_index with signed offset.
+       * stor-layout.c (initialize_sizetypes): sizetypes no longer
+       sign-extend.
+       (layout_type): For zero-sized arrays ignore overflow on the
+       size calculations.
+       * tree-ssa-ccp.c (bit_value_unop_1): Likewise.
+       (bit_value_binop_1): Likewise.
+       * tree.c (double_int_to_tree): Likewise.
+       (double_int_fits_to_tree_p): Likewise.
+       (force_fit_type_double): Likewise.
+       (host_integerp): Likewise.
+       (int_fits_type_p): Likewise.
+       * varasm.c (output_constructor_regular_field): Sign-extend the
+       field-offset to cater for negative offsets produced by the Ada frontend.
+       * omp-low.c (extract_omp_for_data): Convert the loop step to
+       signed for pointer adjustments.
+
+2012-05-02  Richard Guenther  <rguenther@suse.de>
+
+       * tree.c (valid_constant_size_p): New function.
+       * tree.h (valid_constant_size_p): Declare.
+       * cfgexpand.c (expand_one_var): Adjust check for too large
+       variables by using valid_constant_size_p.
+       * varasm.c (assemble_variable): Likewise.
+
+       * c-decl.c (grokdeclarator): Properly check for sizes that
+       cover more than half of the address-space.
+
 2012-05-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/53163
index 158b3ad0f195116ed7b7a4fca93451b465551fb7..3153cf4e18364d8e55812c5b0aa0b5833402d7ec 100644 (file)
@@ -5811,12 +5811,12 @@ grokdeclarator (const struct c_declarator *declarator,
        }
     }
 
-  /* Did array size calculations overflow?  */
-
+  /* Did array size calculations overflow or does the array cover more
+     than half of the address-space?  */
   if (TREE_CODE (type) == ARRAY_TYPE
       && COMPLETE_TYPE_P (type)
       && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
-      && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
+      && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
     {
       if (name)
        error_at (loc, "size of array %qE is too large", name);
index 9de3e51c673f634cb6a1af4214525bac7e20d6c5..4c27e762df5733ce658fe237b9ae57fde0f304b1 100644 (file)
@@ -1241,8 +1241,9 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
       if (really_expand)
         expand_one_register_var (origvar);
     }
-  else if (!host_integerp (DECL_SIZE_UNIT (var), 1))
+  else if (! valid_constant_size_p (DECL_SIZE_UNIT (var)))
     {
+      /* Reject variables which cover more than half of the address-space.  */
       if (really_expand)
        {
          error ("size of variable %q+D is too large", var);
index e52149f023d45df9e3df55122aeadfceaae885ad..6b0e57cedb53add7b352f05e131afc43465197b6 100644 (file)
@@ -1,3 +1,8 @@
+2012-05-02  Richard Guenther  <rguenther@suse.de>
+
+       * decl.c (grokdeclarator): Properly check for sizes that
+       cover more than half of the address-space.
+
 2012-04-30  Marc Glisse  <marc.glisse@inria.fr>
 
        PR c++/51033
index 40818a3f3ff53d2674cb0d7c2f3cf7e5df9f987b..108b51531d4aafcbb1acbea2f694c5e1c7f5c0ec 100644 (file)
@@ -9672,12 +9672,12 @@ grokdeclarator (const cp_declarator *declarator,
         error ("non-parameter %qs cannot be a parameter pack", name);
     }
 
-  /* Did array size calculations overflow?  */
-
+  /* Did array size calculations overflow or does the array cover more
+     than half of the address-space?  */
   if (TREE_CODE (type) == ARRAY_TYPE
       && COMPLETE_TYPE_P (type)
       && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
-      && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
+      && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
     {
       error ("size of array %qs is too large", name);
       /* If we proceed with the array type as it is, we'll eventually
index 41081ff919c3eb2fe075d5a7842ee99599174e8b..fe12942d9811e13faf42c876a6d3b19c404b5ad5 100644 (file)
@@ -191,9 +191,6 @@ div_if_zero_remainder (enum tree_code code, const_tree arg1, const_tree arg2)
      does the correct thing for POINTER_PLUS_EXPR where we want
      a signed division.  */
   uns = TYPE_UNSIGNED (TREE_TYPE (arg2));
-  if (TREE_CODE (TREE_TYPE (arg2)) == INTEGER_TYPE
-      && TYPE_IS_SIZETYPE (TREE_TYPE (arg2)))
-    uns = false;
 
   quo = double_int_divmod (tree_to_double_int (arg1),
                           tree_to_double_int (arg2),
@@ -935,8 +932,9 @@ int_binop_types_match_p (enum tree_code code, const_tree type1, const_tree type2
    to produce a new constant.  Return NULL_TREE if we don't know how
    to evaluate CODE at compile-time.  */
 
-tree
-int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
+static tree
+int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree arg2,
+                  int overflowable)
 {
   double_int op1, op2, res, tmp;
   tree t;
@@ -1078,13 +1076,19 @@ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
       return NULL_TREE;
     }
 
-  t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
+  t = force_fit_type_double (TREE_TYPE (arg1), res, overflowable,
                             ((!uns || is_sizetype) && overflow)
                             | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
 
   return t;
 }
 
+tree
+int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
+{
+  return int_const_binop_1 (code, arg1, arg2, 1);
+}
+
 /* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
    constant.  We assume ARG1 and ARG2 have the same data type, or at least
    are the same kind of constant and the same machine mode.  Return zero if
@@ -1423,8 +1427,10 @@ size_binop_loc (location_t loc, enum tree_code code, tree arg0, tree arg1)
            return arg1;
        }
 
-      /* Handle general case of two integer constants.  */
-      return int_const_binop (code, arg0, arg1);
+      /* Handle general case of two integer constants.  For sizetype
+         constant calculations we always want to know about overflow,
+        even in the unsigned case.  */
+      return int_const_binop_1 (code, arg0, arg1, -1);
     }
 
   return fold_build2_loc (loc, code, type, arg0, arg1);
@@ -5908,11 +5914,9 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
         multiple of the other, in which case we replace this with either an
         operation or CODE or TCODE.
 
-        If we have an unsigned type that is not a sizetype, we cannot do
-        this since it will change the result if the original computation
-        overflowed.  */
-      if ((TYPE_OVERFLOW_UNDEFINED (ctype)
-          || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
+        If we have an unsigned type, we cannot do this since it will change
+        the result if the original computation overflowed.  */
+      if (TYPE_OVERFLOW_UNDEFINED (ctype)
          && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
              || (tcode == MULT_EXPR
                  && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
@@ -9971,7 +9975,8 @@ fold_binary_loc (location_t loc,
       if (TREE_CODE (arg0) == ADDR_EXPR)
        {
          tem = try_move_mult_to_index (loc, arg0,
-                                       fold_convert_loc (loc, sizetype, arg1));
+                                       fold_convert_loc (loc,
+                                                         ssizetype, arg1));
          if (tem)
            return fold_convert_loc (loc, type, tem);
        }
index ec1a5522d7f8ebcbe830a038beef6fef28fcaf09..f6b62438dcecebaf8ef2150c831826d95be51421 100644 (file)
@@ -336,9 +336,11 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
       switch (TREE_CODE (t))
        {
        case PLUS_EXPR:
-       case POINTER_PLUS_EXPR:
          loop->step = TREE_OPERAND (t, 1);
          break;
+       case POINTER_PLUS_EXPR:
+         loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
+         break;
        case MINUS_EXPR:
          loop->step = TREE_OPERAND (t, 1);
          loop->step = fold_build1_loc (loc,
index e72e7f390910b43d4778f50942fa743160927e3d..12a6c13a6b8d1bf71a57145e71c7beff0ec10b79 100644 (file)
@@ -2182,11 +2182,37 @@ layout_type (tree type)
               that (possible) negative values are handled appropriately
               when determining overflow.  */
            else
-             length
-               = fold_convert (sizetype,
-                               size_binop (PLUS_EXPR,
-                                           build_int_cst (TREE_TYPE (lb), 1),
-                                           size_binop (MINUS_EXPR, ub, lb)));
+             {
+               /* ???  When it is obvious that the range is signed
+                  represent it using ssizetype.  */
+               if (TREE_CODE (lb) == INTEGER_CST
+                   && TREE_CODE (ub) == INTEGER_CST
+                   && TYPE_UNSIGNED (TREE_TYPE (lb))
+                   && tree_int_cst_lt (ub, lb))
+                 {
+                   lb = double_int_to_tree
+                          (ssizetype,
+                           double_int_sext (tree_to_double_int (lb),
+                                            TYPE_PRECISION (TREE_TYPE (lb))));
+                   ub = double_int_to_tree
+                          (ssizetype,
+                           double_int_sext (tree_to_double_int (ub),
+                                            TYPE_PRECISION (TREE_TYPE (ub))));
+                 }
+               length
+                 = fold_convert (sizetype,
+                                 size_binop (PLUS_EXPR,
+                                             build_int_cst (TREE_TYPE (lb), 1),
+                                             size_binop (MINUS_EXPR, ub, lb)));
+             }
+
+           /* If we arrived at a length of zero ignore any overflow
+              that occured as part of the calculation.  There exists
+              an association of the plus one where that overflow would
+              not happen.  */
+           if (integer_zerop (length)
+               && TREE_OVERFLOW (length))
+             length = size_zero_node;
 
            TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
                                           fold_convert (bitsizetype,
@@ -2453,11 +2479,6 @@ initialize_sizetypes (void)
   TYPE_SIZE_UNIT (sizetype) = size_int (GET_MODE_SIZE (TYPE_MODE (sizetype)));
   set_min_and_max_values_for_integral_type (sizetype, precision,
                                            /*is_unsigned=*/true);
-  /* sizetype is unsigned but we need to fix TYPE_MAX_VALUE so that it is
-     sign-extended in a way consistent with force_fit_type.  */
-  TYPE_MAX_VALUE (sizetype)
-    = double_int_to_tree (sizetype,
-                         tree_to_double_int (TYPE_MAX_VALUE (sizetype)));
 
   SET_TYPE_MODE (bitsizetype, smallest_mode_for_size (bprecision, MODE_INT));
   TYPE_ALIGN (bitsizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (bitsizetype));
@@ -2466,11 +2487,6 @@ initialize_sizetypes (void)
     = size_int (GET_MODE_SIZE (TYPE_MODE (bitsizetype)));
   set_min_and_max_values_for_integral_type (bitsizetype, bprecision,
                                            /*is_unsigned=*/true);
-  /* bitsizetype is unsigned but we need to fix TYPE_MAX_VALUE so that it is
-     sign-extended in a way consistent with force_fit_type.  */
-  TYPE_MAX_VALUE (bitsizetype)
-    = double_int_to_tree (bitsizetype,
-                         tree_to_double_int (TYPE_MAX_VALUE (bitsizetype)));
 
   /* Create the signed variants of *sizetype.  */
   ssizetype = make_signed_type (TYPE_PRECISION (sizetype));
index b2055433beb19b302a0ae0f846ff5be2cdacc077..95650152046199a584ae54c81c5845b700df439a 100644 (file)
@@ -1,3 +1,7 @@
+2012-05-02  Richard Guenther  <rguenther@suse.de>
+
+       * g++.dg/tree-ssa/pr19807.C: Adjust.
+
 2012-05-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/53163
index bba79a9d150def9cb0dd4eb5ae8f66a6a831f725..0eeeb18abda5c85e3dee7fed90e52a954e11c2d1 100644 (file)
@@ -25,6 +25,6 @@ void bar(int i)
    Simply test for the existence of +1 and -1 once, which also ensures
    the above.  If the addition/subtraction would be applied to the
    pointer we would instead see +-4 (or 8, depending on sizeof(int)).  */
-/* { dg-final { scan-tree-dump-times "\\\+ -1;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump "\\\+ (0x0f*|18446744073709551615|4294967295|-1);" "optimized" } } */
 /* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
index 4e86b8db0c32abc7afabed30f68c62e2d45240b6..1257b8bf7ba2680eab4fda060e0c86a7b78832aa 100644 (file)
@@ -1101,14 +1101,12 @@ bit_value_unop_1 (enum tree_code code, tree type,
        bool uns;
 
        /* First extend mask and value according to the original type.  */
-       uns = (TREE_CODE (rtype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (rtype)
-              ? 0 : TYPE_UNSIGNED (rtype));
+       uns = TYPE_UNSIGNED (rtype);
        *mask = double_int_ext (rmask, TYPE_PRECISION (rtype), uns);
        *val = double_int_ext (rval, TYPE_PRECISION (rtype), uns);
 
        /* Then extend mask and value according to the target type.  */
-       uns = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
-              ? 0 : TYPE_UNSIGNED (type));
+       uns = TYPE_UNSIGNED (type);
        *mask = double_int_ext (*mask, TYPE_PRECISION (type), uns);
        *val = double_int_ext (*val, TYPE_PRECISION (type), uns);
        break;
@@ -1130,8 +1128,7 @@ bit_value_binop_1 (enum tree_code code, tree type,
                   tree r1type, double_int r1val, double_int r1mask,
                   tree r2type, double_int r2val, double_int r2mask)
 {
-  bool uns = (TREE_CODE (type) == INTEGER_TYPE
-             && TYPE_IS_SIZETYPE (type) ? 0 : TYPE_UNSIGNED (type));
+  bool uns = TYPE_UNSIGNED (type);
   /* Assume we'll get a constant result.  Use an initial varying value,
      we fall back to varying in the end if necessary.  */
   *mask = double_int_minus_one;
@@ -1198,13 +1195,6 @@ bit_value_binop_1 (enum tree_code code, tree type,
            }
          else if (shift < 0)
            {
-             /* ???  We can have sizetype related inconsistencies in
-                the IL.  */
-             if ((TREE_CODE (r1type) == INTEGER_TYPE
-                  && (TYPE_IS_SIZETYPE (r1type)
-                      ? 0 : TYPE_UNSIGNED (r1type))) != uns)
-               break;
-
              shift = -shift;
              *mask = double_int_rshift (r1mask, shift,
                                         TYPE_PRECISION (type), !uns);
@@ -1316,12 +1306,7 @@ bit_value_binop_1 (enum tree_code code, tree type,
          break;
 
        /* For comparisons the signedness is in the comparison operands.  */
-       uns = (TREE_CODE (r1type) == INTEGER_TYPE
-              && TYPE_IS_SIZETYPE (r1type) ? 0 : TYPE_UNSIGNED (r1type));
-       /* ???  We can have sizetype related inconsistencies in the IL.  */
-       if ((TREE_CODE (r2type) == INTEGER_TYPE
-            && TYPE_IS_SIZETYPE (r2type) ? 0 : TYPE_UNSIGNED (r2type)) != uns)
-         break;
+       uns = TYPE_UNSIGNED (r1type);
 
        /* If we know the most significant bits we know the values
           value ranges by means of treating varying bits as zero
index 4623d3765e4261c94d50800b318712532b1f17d0..1ee3f1db51e4a7a67f60bc65b3750e3cb15486c9 100644 (file)
@@ -1062,10 +1062,7 @@ build_int_cst_type (tree type, HOST_WIDE_INT low)
 tree
 double_int_to_tree (tree type, double_int cst)
 {
-  /* Size types *are* sign extended.  */
-  bool sign_extended_type = (!TYPE_UNSIGNED (type)
-                            || (TREE_CODE (type) == INTEGER_TYPE
-                                && TYPE_IS_SIZETYPE (type)));
+  bool sign_extended_type = !TYPE_UNSIGNED (type);
 
   cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
 
@@ -1079,9 +1076,7 @@ bool
 double_int_fits_to_tree_p (const_tree type, double_int cst)
 {
   /* Size types *are* sign extended.  */
-  bool sign_extended_type = (!TYPE_UNSIGNED (type)
-                            || (TREE_CODE (type) == INTEGER_TYPE
-                                && TYPE_IS_SIZETYPE (type)));
+  bool sign_extended_type = !TYPE_UNSIGNED (type);
 
   double_int ext
     = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
@@ -1111,9 +1106,7 @@ force_fit_type_double (tree type, double_int cst, int overflowable,
   bool sign_extended_type;
 
   /* Size types *are* sign extended.  */
-  sign_extended_type = (!TYPE_UNSIGNED (type)
-                        || (TREE_CODE (type) == INTEGER_TYPE
-                            && TYPE_IS_SIZETYPE (type)));
+  sign_extended_type = !TYPE_UNSIGNED (type);
 
   /* If we need to set overflow flags, return a new unshared node.  */
   if (overflowed || !double_int_fits_to_tree_p(type, cst))
@@ -6553,9 +6546,7 @@ host_integerp (const_tree t, int pos)
               && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
              || (! pos && TREE_INT_CST_HIGH (t) == -1
                  && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
-                 && (!TYPE_UNSIGNED (TREE_TYPE (t))
-                     || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
-                         && TYPE_IS_SIZETYPE (TREE_TYPE (t)))))
+                 && !TYPE_UNSIGNED (TREE_TYPE (t)))
              || (pos && TREE_INT_CST_HIGH (t) == 0)));
 }
 
@@ -6850,6 +6841,20 @@ compare_tree_int (const_tree t, unsigned HOST_WIDE_INT u)
     return 1;
 }
 
+/* Return true if SIZE represents a constant size that is in bounds of
+   what the middle-end and the backend accepts (covering not more than
+   half of the address-space).  */
+
+bool
+valid_constant_size_p (const_tree size)
+{
+  if (! host_integerp (size, 1)
+      || TREE_OVERFLOW (size)
+      || tree_int_cst_sign_bit (size) != 0)
+    return false;
+  return true;
+}
+
 /* Return true if CODE represents an associative tree code.  Otherwise
    return false.  */
 bool
@@ -8276,18 +8281,6 @@ int_fits_type_p (const_tree c, const_tree type)
   dc = tree_to_double_int (c);
   unsc = TYPE_UNSIGNED (TREE_TYPE (c));
 
-  if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE
-      && TYPE_IS_SIZETYPE (TREE_TYPE (c))
-      && unsc)
-    /* So c is an unsigned integer whose type is sizetype and type is not.
-       sizetype'd integers are sign extended even though they are
-       unsigned. If the integer value fits in the lower end word of c,
-       and if the higher end word has all its bits set to 1, that
-       means the higher end bits are set to 1 only for sign extension.
-       So let's convert c into an equivalent zero extended unsigned
-       integer.  */
-    dc = double_int_zext (dc, TYPE_PRECISION (TREE_TYPE (c)));
-
 retry:
   type_low_bound = TYPE_MIN_VALUE (type);
   type_high_bound = TYPE_MAX_VALUE (type);
@@ -8306,10 +8299,6 @@ retry:
   if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
     {
       dd = tree_to_double_int (type_low_bound);
-      if (TREE_CODE (type) == INTEGER_TYPE
-         && TYPE_IS_SIZETYPE (type)
-         && TYPE_UNSIGNED (type))
-       dd = double_int_zext (dd, TYPE_PRECISION (type));
       if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_low_bound)))
        {
          int c_neg = (!unsc && double_int_negative_p (dc));
@@ -8331,10 +8320,6 @@ retry:
   if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
     {
       dd = tree_to_double_int (type_high_bound);
-      if (TREE_CODE (type) == INTEGER_TYPE
-         && TYPE_IS_SIZETYPE (type)
-         && TYPE_UNSIGNED (type))
-       dd = double_int_zext (dd, TYPE_PRECISION (type));
       if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_high_bound)))
        {
          int c_neg = (!unsc && double_int_negative_p (dc));
index e719be2ed40772313f5210ca5c6b782996624799..3d7fcabe142f0a975bac974585f6c1470601f6ef 100644 (file)
@@ -4451,6 +4451,7 @@ extern bool tree_expr_nonnegative_warnv_p (tree, bool *);
 extern bool may_negate_without_overflow_p (const_tree);
 extern tree strip_array_types (tree);
 extern tree excess_precision_type (tree);
+extern bool valid_constant_size_p (const_tree);
 
 /* Construct various nodes representing fract or accum data types.  */
 
index 03ac49b4677d691030919aa41601af82e4095097..ce9e328036492229c527cee4f17d404e772f5356 100644 (file)
@@ -1992,7 +1992,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
     return;
 
   if (! dont_output_data
-      && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
+      && ! valid_constant_size_p (DECL_SIZE_UNIT (decl)))
     {
       error ("size of variable %q+D is too large", decl);
       return;
@@ -4773,9 +4773,13 @@ output_constructor_regular_field (oc_local_state *local)
 
   if (local->index != NULL_TREE)
     {
+      /* Perform the index calculation in modulo arithmetic but
+        sign-extend the result because Ada has negative DECL_FIELD_OFFSETs
+        but we are using an unsigned sizetype.  */
+      unsigned prec = TYPE_PRECISION (sizetype);
       double_int idx = double_int_sub (tree_to_double_int (local->index),
                                       tree_to_double_int (local->min_index));
-      gcc_assert (double_int_fits_in_shwi_p (idx));
+      idx = double_int_sext (idx, prec);
       fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
                  * idx.low);
     }