On Tue, 24 Apr 2012, Richard Guenther wrote: > > I've been carrying this patch for quite some while now and really > want to go forward with it - the problem is that while all default > languages work fine after this patch Ada shows some testsuite > regressions. I've had various hacks/workarounds throughout the > Ada frontend for them, but lost track of what fixed what and > they all felt like hacks anyway. > > Thus - I know the patch will add Ada testsuite regressions. But it will > not break Ada bootstrap. Ada is not in the set of default languages, > nor is it considered release critical. > > Are the Ada folks happy with helping to fix the fallout after-the-fact > (I got Eric to fix the bootstrap issues that were first present - thanks > for that)? I am happy to revisit my hacks/workarounds and post them, > but it will be ultimatively easier to review them if you can see > the FAIL for yourself (there are some workarounds/hacks posted on the > mailinglist for previous attempts IIRC). > > Thanks for your consideration. > > The patch is currently under re-testing (it needs the 2nd patch > below, which was already approved but back in time broke Ada > bootstrap - I didn't verify if that still occurs).
To followup myself - bootstrap with just the 2nd patch is still broken: /abuild/rguenther/obj2/./gcc/xgcc -B/abuild/rguenther/obj2/./gcc/ -B/usr/local/x86_64-unknown-linux-gnu/bin/ -B/usr/local/x86_64-unknown-linux-gnu/lib/ -isystem /usr/local/x86_64-unknown-linux-gnu/include -isystem /usr/local/x86_64-unknown-linux-gnu/sys-include -c -g -O2 -m32 -fpic -W -Wall -gnatpg -nostdinc -m32 s-secsta.adb -o s-secsta.o s-secsta.adb:501:4: error: size of variable 'System.Secondary_Stack.Chunk' is too large Chunk : aliased Chunk_Id (1, Static_Secondary_Stack_Size); ^ make[9]: *** [s-secsta.o] Error 1 And the following is the list of regressions introduced by the combined patch set: === 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 === acats Summary === # of expected passes 2297 # of unexpected failures 23 === gnat tests === Running target unix/ 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/renaming5.adb scan-tree-dump-times optimized "goto" 2 FAIL: gnat.dg/return3.adb scan-assembler loc 1 6 FAIL: gnat.dg/test_8bitlong_overflow.adb (test for excess errors) FAIL: gnat.dg/test_8bitlong_overflow.adb execution test === gnat Summary for unix/ === # of expected passes 1089 # of unexpected failures 8 # of expected failures 13 # of unsupported tests 2 Running target unix//-m32 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/renaming5.adb scan-tree-dump-times optimized "goto" 2 FAIL: gnat.dg/return3.adb scan-assembler loc 1 6 FAIL: gnat.dg/test_8bitlong_overflow.adb (test for excess errors) FAIL: gnat.dg/test_8bitlong_overflow.adb execution test === gnat Summary for unix//-m32 === # of expected passes 1089 # of unexpected failures 8 # of expected failures 13 # of unsupported tests 2 === gnat Summary === # of expected passes 2178 # of unexpected failures 16 # of expected failures 26 # of unsupported tests 4 Most of the ACATS errors are "raised STORAGE_ERROR : object too large" or "error: size of variable '...' is too large". The gnat testsuite adds "warning: "Storage_Error" will be raised at run time" to this. I remember one workaround (which usually involves re-setting TREE_OVERFLOW at strathegic places) fixes most of ACATS. I'll try to isolate that (but it's a hack and does not feel "right"). Richard. > 2012-03-06 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. > * 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. > > Index: trunk/gcc/fold-const.c > =================================================================== > *** trunk.orig/gcc/fold-const.c 2012-03-06 12:41:10.000000000 +0100 > --- trunk/gcc/fold-const.c 2012-03-06 14:46:25.000000000 +0100 > *************** div_if_zero_remainder (enum tree_code co > *** 191,199 **** > 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), > --- 191,196 ---- > *************** int_binop_types_match_p (enum tree_code > *** 935,942 **** > 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; > --- 932,940 ---- > 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 > *** 1078,1090 **** > 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 > --- 1076,1094 ---- > 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 > *** 1445,1452 **** > 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); > --- 1449,1458 ---- > 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 > *** 5924,5934 **** > 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 > --- 5930,5938 ---- > 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, > *** 9953,9959 **** > 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); > } > --- 9957,9964 ---- > 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 2012-03-06 11:36:46.000000000 +0100 > --- trunk/gcc/stor-layout.c 2012-03-06 14:46:25.000000000 +0100 > *************** layout_type (tree type) > *** 1970,1975 **** > --- 1970,1983 ---- > 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) > *** 2235,2245 **** > 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)); > --- 2243,2248 ---- > *************** initialize_sizetypes (void) > *** 2248,2258 **** > = 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)); > --- 2251,2256 ---- > Index: trunk/gcc/tree-ssa-ccp.c > =================================================================== > *** trunk.orig/gcc/tree-ssa-ccp.c 2012-03-06 11:36:46.000000000 +0100 > --- trunk/gcc/tree-ssa-ccp.c 2012-03-06 14:46:25.000000000 +0100 > *************** bit_value_unop_1 (enum tree_code code, t > *** 1101,1114 **** > 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; > --- 1101,1112 ---- > 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, > *** 1130,1137 **** > 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; > --- 1128,1134 ---- > 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, > *** 1198,1210 **** > } > 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); > --- 1195,1200 ---- > *************** bit_value_binop_1 (enum tree_code code, > *** 1316,1327 **** > 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 > --- 1306,1312 ---- > 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 2012-03-06 14:46:08.000000000 +0100 > --- trunk/gcc/tree.c 2012-03-06 14:53:36.000000000 +0100 > *************** 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) > *** 6532,6540 **** > && (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))); > } > > --- 6526,6532 ---- > && (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))); > } > > *************** int_fits_type_p (const_tree c, const_tre > *** 8264,8281 **** > 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); > --- 8256,8261 ---- > *************** retry: > *** 8294,8303 **** > 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)); > --- 8274,8279 ---- > *************** retry: > *** 8319,8328 **** > 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)); > --- 8295,8300 ---- > Index: trunk/gcc/varasm.c > =================================================================== > *** trunk.orig/gcc/varasm.c 2012-03-06 14:46:08.000000000 +0100 > --- trunk/gcc/varasm.c 2012-03-06 14:48:30.000000000 +0100 > *************** output_constructor_regular_field (oc_loc > *** 4756,4764 **** > > 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); > } > --- 4756,4768 ---- > > 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)); > ! idx = double_int_sext (idx, prec); > 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 2012-03-06 11:36:46.000000000 +0100 > --- trunk/gcc/omp-low.c 2012-03-06 14:46:25.000000000 +0100 > *************** extract_omp_for_data (gimple for_stmt, s > *** 336,344 **** > 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, > --- 336,346 ---- > 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/testsuite/g++.dg/tree-ssa/pr19807.C > =================================================================== > *** trunk.orig/gcc/testsuite/g++.dg/tree-ssa/pr19807.C 2012-03-06 > 11:36:46.000000000 +0100 > --- trunk/gcc/testsuite/g++.dg/tree-ssa/pr19807.C 2012-03-06 > 14:46:25.000000000 +0100 > *************** 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" } } */ > > > > > 2012-03-06 Richard Guenther <rguent...@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. > > Index: trunk/gcc/tree.c > =================================================================== > *** trunk.orig/gcc/tree.c 2012-03-06 13:54:25.000000000 +0100 > --- trunk/gcc/tree.c 2012-03-06 14:46:08.000000000 +0100 > *************** compare_tree_int (const_tree t, unsigned > *** 6829,6834 **** > --- 6829,6848 ---- > 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 > Index: trunk/gcc/varasm.c > =================================================================== > *** trunk.orig/gcc/varasm.c 2012-03-06 13:54:25.000000000 +0100 > --- trunk/gcc/varasm.c 2012-03-06 14:46:08.000000000 +0100 > *************** assemble_variable (tree decl, int top_le > *** 1987,1993 **** > return; > > if (! dont_output_data > ! && ! host_integerp (DECL_SIZE_UNIT (decl), 1)) > { > error ("size of variable %q+D is too large", decl); > return; > --- 1987,1993 ---- > return; > > if (! dont_output_data > ! && ! valid_constant_size_p (DECL_SIZE_UNIT (decl))) > { > error ("size of variable %q+D is too large", decl); > return; > Index: trunk/gcc/c-decl.c > =================================================================== > *** trunk.orig/gcc/c-decl.c 2012-03-06 13:54:25.000000000 +0100 > --- trunk/gcc/c-decl.c 2012-03-06 14:46:08.000000000 +0100 > *************** grokdeclarator (const struct c_declarato > *** 5798,5809 **** > } > } > > ! /* 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); > --- 5798,5809 ---- > } > } > > ! /* 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 2012-03-06 13:54:25.000000000 +0100 > --- trunk/gcc/cp/decl.c 2012-03-06 14:46:08.000000000 +0100 > *************** grokdeclarator (const cp_declarator *dec > *** 9635,9646 **** > 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 > --- 9635,9646 ---- > 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/cfgexpand.c > =================================================================== > *** trunk.orig/gcc/cfgexpand.c 2012-03-06 13:54:25.000000000 +0100 > --- trunk/gcc/cfgexpand.c 2012-03-06 14:46:08.000000000 +0100 > *************** expand_one_var (tree var, bool toplevel, > *** 1238,1245 **** > 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); > --- 1238,1246 ---- > 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 2012-03-06 13:54:25.000000000 +0100 > --- trunk/gcc/tree.h 2012-03-06 14:46:08.000000000 +0100 > *************** extern bool tree_expr_nonnegative_warnv_ > *** 4439,4444 **** > --- 4439,4445 ---- > 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. */ > > -- Richard Guenther <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer