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. */