This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
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 <rguenther@suse.de>
* tree.c (valid_constant_size_p): New function.
* tree.h (valid_constant_size_p): Declare.
* cfgexpand.c (expand_one_var): Adjust check for too large
variables by using valid_constant_size_p.
* varasm.c (assemble_variable): Likewise.
c/
* c-decl.c (grokdeclarator): Properly check for sizes that
cover more than half of the address-space.
cp/
* decl.c (grokdeclarator): Properly check for sizes that
cover more than half of the address-space.
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 <rguenther@suse.de>
* fold-const.c (div_if_zero_remainder): sizetypes no longer
sign-extend.
(int_const_binop_1): New worker for int_const_binop with
overflowable parameter. Pass it through
to force_fit_type_double.
(int_const_binop): Wrap around int_const_binop_1 with overflowable
equal to one.
(size_binop_loc): Call int_const_binop_1 with overflowable equal
to minus one, forcing overflow detection for even unsigned types.
(extract_muldiv_1): Remove bogus TYPE_IS_SIZETYPE special-casing.
(fold_binary_loc): Call try_move_mult_to_index with signed offset.
* stor-layout.c (initialize_sizetypes): sizetypes no longer
sign-extend.
(layout_type): For zero-sized arrays ignore overflow on the
size calculations.
* tree-ssa-ccp.c (bit_value_unop_1): Likewise.
(bit_value_binop_1): Likewise.
* tree.c (double_int_to_tree): Likewise.
(double_int_fits_to_tree_p): Likewise.
(force_fit_type_double): Likewise.
(host_integerp): Likewise.
(int_fits_type_p): Likewise.
* varasm.c (output_constructor_regular_field): Sign-extend the
field-offset to cater for negative offsets produced by the Ada frontend.
* omp-low.c (extract_omp_for_data): Convert the loop step to
signed for pointer adjustments.
* g++.dg/tree-ssa/pr19807.C: Adjust.
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" } } */