This is the minimal patch that allows Ada to bootstrap (including
all the other frontend changes to make them regression-free).  It
doesn't need any Ada changes for this.

I will send out Ada changes separately, piecewise, indicating which
regressions they will fix - I'd appreciate help there though, as most
"fixes" rather fix the issues where symptoms occur which is not
necessarily the best place.

In the generic parts what changed compared to the last patch is
folding in of the reverted extract_muldiv_1 change, allowing
zero-size arrays in layout_type by ignoring overflow (with good
reasoning) and folding the host_integerp (.., 1) && tree_int_cst_sign_bit 
() && TREE_OVERFLOW check into a new valid_constant_size_p predicate.

Bootstrapped and tested on x86_64-unknown-linux-gnu with
--enable-languages=ada (which enables C and C++ as well, previous
versions bootstrapped and tested for all languages).

Ada fails from this patch:

                === acats tests ===
FAIL:   a71004a
FAIL:   c36204d
FAIL:   c36205l
FAIL:   c37404b
FAIL:   c41107a
FAIL:   c41204a
FAIL:   c43204c
FAIL:   c43204e
FAIL:   c43204f
FAIL:   c43204g
FAIL:   c43204h
FAIL:   c43204i
FAIL:   c52102a
FAIL:   c52102c
FAIL:   c64103c
FAIL:   c64103d
FAIL:   c64106a
FAIL:   c95087a
FAIL:   cc1224a
FAIL:   cc1311a
FAIL:   cc3106b
FAIL:   cc3224a
FAIL:   cd2a31a
FAIL:   cxb3009

                === acats Summary ===
# of expected passes            2297
# of unexpected failures        24

                === gnat tests ===


Running target unix/
FAIL: gnat.dg/align_max.adb execution test
FAIL: gnat.dg/array11.adb  (test for warnings, line 12)
FAIL: gnat.dg/loop_optimization3.adb (test for excess errors)
FAIL: gnat.dg/loop_optimization3.adb execution test
FAIL: gnat.dg/object_overflow.adb  (test for warnings, line 8)
FAIL: gnat.dg/test_8bitlong_overflow.adb (test for excess errors)
WARNING: gnat.dg/test_8bitlong_overflow.adb compilation failed to produce 
execut
able
FAIL: gnat.dg/thin_pointer2.adb execution test
FAIL: gnat.dg/unc_memfree.adb execution test

                === gnat Summary for unix/ ===

# of expected passes            910
# of unexpected failures        8
# of expected failures          11
# of unsupported tests          2

Running target unix//-m32
FAIL: gnat.dg/align_max.adb execution test
FAIL: gnat.dg/array11.adb  (test for warnings, line 12)
FAIL: gnat.dg/frame_overflow.adb  (test for errors, line 17)
FAIL: gnat.dg/frame_overflow.adb  (test for errors, line 24)
FAIL: gnat.dg/loop_optimization3.adb (test for excess errors)
FAIL: gnat.dg/loop_optimization3.adb execution test
FAIL: gnat.dg/object_overflow.adb  (test for warnings, line 8)
FAIL: gnat.dg/test_8bitlong_overflow.adb (test for excess errors)
WARNING: gnat.dg/test_8bitlong_overflow.adb compilation failed to produce 
execut
able
FAIL: gnat.dg/thin_pointer2.adb execution test
FAIL: gnat.dg/unc_memfree.adb execution test

                === gnat Summary for unix//-m32 ===

# of expected passes            908
# of unexpected failures        10
# of expected failures          11
# of unsupported tests          2

                === gnat Summary ===

# of expected passes            1818
# of unexpected failures        18
# of expected failures          22
# of unsupported tests          4

Richard.

2011-09-05  Richard Guenther  <rguent...@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.
        (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.
        (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.

        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.

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

Index: trunk/gcc/fold-const.c
===================================================================
*** trunk.orig/gcc/fold-const.c 2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/fold-const.c      2011-09-05 11:41:45.000000000 +0200
*************** div_if_zero_remainder (enum tree_code co
*** 194,202 ****
       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),
--- 194,199 ----
*************** int_binop_types_match_p (enum tree_code
*** 938,945 ****
     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)
  {
    double_int op1, op2, res, tmp;
    tree t;
--- 935,943 ----
     to produce a new constant.  Return NULL_TREE if we don't know how
     to evaluate CODE at compile-time.  */
  
! 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;
*************** int_const_binop (enum tree_code code, co
*** 1081,1093 ****
        return NULL_TREE;
      }
  
!   t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
                             ((!uns || is_sizetype) && overflow)
                             | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
  
    return t;
  }
  
  /* 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
--- 1079,1097 ----
        return NULL_TREE;
      }
  
!   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
*************** size_binop_loc (location_t loc, enum tre
*** 1448,1455 ****
            return arg1;
        }
  
!       /* Handle general case of two integer constants.  */
!       return int_const_binop (code, arg0, arg1);
      }
  
    return fold_build2_loc (loc, code, type, arg0, arg1);
--- 1452,1461 ----
            return 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);
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 5888,5898 ****
         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)))
          && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
              || (tcode == MULT_EXPR
                  && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
--- 5894,5902 ----
         multiple of the other, in which case we replace this with either an
         operation or CODE or TCODE.
  
!        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
*************** fold_binary_loc (location_t loc,
*** 9601,9607 ****
        if (TREE_CODE (arg0) == ADDR_EXPR)
        {
          tem = try_move_mult_to_index (loc, arg0,
!                                       fold_convert_loc (loc, sizetype, arg1));
          if (tem)
            return fold_convert_loc (loc, type, tem);
        }
--- 9605,9612 ----
        if (TREE_CODE (arg0) == ADDR_EXPR)
        {
          tem = try_move_mult_to_index (loc, arg0,
!                                       fold_convert_loc (loc,
!                                                         ssizetype, arg1));
          if (tem)
            return fold_convert_loc (loc, type, tem);
        }
Index: trunk/gcc/stor-layout.c
===================================================================
*** trunk.orig/gcc/stor-layout.c        2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/stor-layout.c     2011-09-05 12:40:10.000000000 +0200
*************** layout_type (tree type)
*** 1969,1974 ****
--- 1969,1982 ----
                                            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,
                                                         length));
*************** initialize_sizetypes (void)
*** 2234,2244 ****
    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));
--- 2242,2247 ----
*************** initialize_sizetypes (void)
*** 2247,2257 ****
      = 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));
--- 2250,2255 ----
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c       2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/tree-ssa-ccp.c    2011-09-05 11:41:45.000000000 +0200
*************** bit_value_unop_1 (enum tree_code code, t
*** 1100,1113 ****
        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));
        *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));
        *mask = double_int_ext (*mask, TYPE_PRECISION (type), uns);
        *val = double_int_ext (*val, TYPE_PRECISION (type), uns);
        break;
--- 1100,1111 ----
        bool uns;
  
        /* First extend mask and value according to the original type.  */
!       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 = TYPE_UNSIGNED (type);
        *mask = double_int_ext (*mask, TYPE_PRECISION (type), uns);
        *val = double_int_ext (*val, TYPE_PRECISION (type), uns);
        break;
*************** bit_value_binop_1 (enum tree_code code,
*** 1129,1136 ****
                   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));
    /* 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;
--- 1127,1133 ----
                   tree r1type, double_int r1val, double_int r1mask,
                   tree r2type, double_int r2val, double_int r2mask)
  {
!   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;
*************** bit_value_binop_1 (enum tree_code code,
*** 1197,1209 ****
            }
          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);
--- 1194,1199 ----
*************** bit_value_binop_1 (enum tree_code code,
*** 1315,1326 ****
          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;
  
        /* If we know the most significant bits we know the values
           value ranges by means of treating varying bits as zero
--- 1305,1311 ----
          break;
  
        /* For comparisons the signedness is in the comparison operands.  */
!       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: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c       2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/tree.c    2011-09-05 12:38:56.000000000 +0200
*************** tree
*** 1059,1067 ****
  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)));
  
    cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
  
--- 1059,1065 ----
  double_int_to_tree (tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = !TYPE_UNSIGNED (type);
  
    cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
  
*************** bool
*** 1075,1083 ****
  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)));
  
    double_int ext
      = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
--- 1073,1079 ----
  double_int_fits_to_tree_p (const_tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = !TYPE_UNSIGNED (type);
  
    double_int ext
      = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
*************** force_fit_type_double (tree type, double
*** 1107,1115 ****
    bool sign_extended_type;
  
    /* Size types *are* sign extended.  */
!   sign_extended_type = (!TYPE_UNSIGNED (type)
!                         || (TREE_CODE (type) == INTEGER_TYPE
!                             && TYPE_IS_SIZETYPE (type)));
  
    /* If we need to set overflow flags, return a new unshared node.  */
    if (overflowed || !double_int_fits_to_tree_p(type, cst))
--- 1103,1109 ----
    bool sign_extended_type;
  
    /* Size types *are* sign extended.  */
!   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))
*************** host_integerp (const_tree t, int pos)
*** 6496,6504 ****
               && (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)))))
              || (pos && TREE_INT_CST_HIGH (t) == 0)));
  }
  
--- 6490,6496 ----
               && (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)))
              || (pos && TREE_INT_CST_HIGH (t) == 0)));
  }
  
*************** compare_tree_int (const_tree t, unsigned
*** 6782,6787 ****
--- 6774,6793 ----
      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
*************** int_fits_type_p (const_tree c, const_tre
*** 8190,8207 ****
    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);
--- 8196,8201 ----
*************** retry:
*** 8220,8229 ****
    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));
--- 8214,8219 ----
*************** retry:
*** 8245,8254 ****
    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));
--- 8235,8240 ----
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c     2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/varasm.c  2011-09-05 11:41:45.000000000 +0200
*************** assemble_variable (tree decl, int top_le
*** 1980,1986 ****
      return;
  
    if (! dont_output_data
!       && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
      {
        error ("size of variable %q+D is too large", decl);
        return;
--- 1980,1986 ----
      return;
  
    if (! dont_output_data
!       && ! valid_constant_size_p (DECL_SIZE_UNIT (decl)))
      {
        error ("size of variable %q+D is too large", decl);
        return;
*************** output_constructor_regular_field (oc_loc
*** 4746,4753 ****
  
    if (local->index != NULL_TREE)
      {
!       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));
        fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
                  * idx.low);
--- 4746,4760 ----
  
    if (local->index != NULL_TREE)
      {
!       /* ???  Ada has negative DECL_FIELD_OFFSETs but we are using an
!          unsigned sizetype so make sure to sign-extend the indices before
!        subtracting them.  */
!       unsigned prec = TYPE_PRECISION (sizetype);
!       double_int idx
!       = double_int_sub (double_int_sext (tree_to_double_int (local->index),
!                                          prec),
!                         double_int_sext (tree_to_double_int
!                                            (local->min_index), prec));
        gcc_assert (double_int_fits_in_shwi_p (idx));
        fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
                  * idx.low);
Index: trunk/gcc/omp-low.c
===================================================================
*** trunk.orig/gcc/omp-low.c    2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/omp-low.c 2011-09-05 11:41:45.000000000 +0200
*************** extract_omp_for_data (gimple for_stmt, s
*** 335,343 ****
        switch (TREE_CODE (t))
        {
        case PLUS_EXPR:
-       case POINTER_PLUS_EXPR:
          loop->step = TREE_OPERAND (t, 1);
          break;
        case MINUS_EXPR:
          loop->step = TREE_OPERAND (t, 1);
          loop->step = fold_build1_loc (loc,
--- 335,345 ----
        switch (TREE_CODE (t))
        {
        case 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: trunk/gcc/c-decl.c
===================================================================
*** trunk.orig/gcc/c-decl.c     2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/c-decl.c  2011-09-05 11:41:45.000000000 +0200
*************** grokdeclarator (const struct c_declarato
*** 5708,5719 ****
    if (bitfield)
      check_bitfield_type_and_width (&type, width, name);
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        if (name)
        error_at (loc, "size of array %qE is too large", name);
--- 5708,5719 ----
    if (bitfield)
      check_bitfield_type_and_width (&type, width, name);
  
!   /* 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
!       && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
      {
        if (name)
        error_at (loc, "size of array %qE is too large", name);
Index: trunk/gcc/cp/decl.c
===================================================================
*** trunk.orig/gcc/cp/decl.c    2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/cp/decl.c 2011-09-05 11:41:45.000000000 +0200
*************** grokdeclarator (const cp_declarator *dec
*** 9505,9516 ****
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (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
--- 9505,9516 ----
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* 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
!       && ! 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: trunk/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
===================================================================
*** trunk.orig/gcc/testsuite/g++.dg/tree-ssa/pr19807.C  2011-09-05 
11:40:30.000000000 +0200
--- trunk/gcc/testsuite/g++.dg/tree-ssa/pr19807.C       2011-09-05 
11:41:45.000000000 +0200
*************** void bar(int i)
*** 25,30 ****
     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-times "\\\+ 1;" 1 "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */
--- 25,30 ----
     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 "\\\+ 
(0x0f*|18446744073709551615|4294967295|-1);" "optimized" } } */
  /* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */
Index: trunk/gcc/cfgexpand.c
===================================================================
*** trunk.orig/gcc/cfgexpand.c  2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/cfgexpand.c       2011-09-05 11:41:45.000000000 +0200
*************** expand_one_var (tree var, bool toplevel,
*** 1067,1074 ****
        if (really_expand)
          expand_one_register_var (origvar);
      }
!   else if (!host_integerp (DECL_SIZE_UNIT (var), 1))
      {
        if (really_expand)
        {
          error ("size of variable %q+D is too large", var);
--- 1067,1075 ----
        if (really_expand)
          expand_one_register_var (origvar);
      }
!   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: trunk/gcc/tree.h
===================================================================
*** trunk.orig/gcc/tree.h       2011-09-05 11:40:30.000000000 +0200
--- trunk/gcc/tree.h    2011-09-05 11:41:45.000000000 +0200
*************** extern bool tree_expr_nonnegative_warnv_
*** 4388,4393 ****
--- 4388,4394 ----
  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.  */
  

Reply via email to