On Fri, 9 Mar 2012, Eric Botcazou wrote: > > Well. I suppose fixing that negative DECL_FIELD_OFFSET thing should > > be #1 priority. > > Tentative patch attached (you need an up-to-date tree). We cannot really get > rid of the negative offsets for thin pointers, so the patch pulls them out of > record types and uses pointer arithmetics instead.
Thanks. That seems to get me into Ada bootstrap land together with the following two patches applied (but not when I apply only the first patch due to the stale TREE_OVERFLOW bits on type/decl sizes). Richard. 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. */ 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" } } */