mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-24 05:19:13 +08:00
tree.c (valid_constant_size_p): New function.
2012-05-02 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. 2012-05-02 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. From-SVN: r187042
This commit is contained in:
parent
795e8869fd
commit
56099f00a5
@ -1,3 +1,43 @@
|
||||
2012-05-02 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.
|
||||
|
||||
2012-05-02 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-decl.c (grokdeclarator): Properly check for sizes that
|
||||
cover more than half of the address-space.
|
||||
|
||||
2012-05-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/53163
|
||||
|
@ -5811,12 +5811,12 @@ grokdeclarator (const struct c_declarator *declarator,
|
||||
}
|
||||
}
|
||||
|
||||
/* Did array size calculations overflow? */
|
||||
|
||||
/* 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
|
||||
&& TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
|
||||
&& ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
|
||||
{
|
||||
if (name)
|
||||
error_at (loc, "size of array %qE is too large", name);
|
||||
|
@ -1241,8 +1241,9 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
|
||||
if (really_expand)
|
||||
expand_one_register_var (origvar);
|
||||
}
|
||||
else if (!host_integerp (DECL_SIZE_UNIT (var), 1))
|
||||
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);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-05-02 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* decl.c (grokdeclarator): Properly check for sizes that
|
||||
cover more than half of the address-space.
|
||||
|
||||
2012-04-30 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/51033
|
||||
|
@ -9672,12 +9672,12 @@ grokdeclarator (const cp_declarator *declarator,
|
||||
error ("non-parameter %qs cannot be a parameter pack", name);
|
||||
}
|
||||
|
||||
/* Did array size calculations overflow? */
|
||||
|
||||
/* 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
|
||||
&& TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
|
||||
&& ! 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
|
||||
|
@ -191,9 +191,6 @@ div_if_zero_remainder (enum tree_code code, const_tree arg1, const_tree arg2)
|
||||
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),
|
||||
@ -935,8 +932,9 @@ int_binop_types_match_p (enum tree_code code, const_tree type1, const_tree type2
|
||||
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)
|
||||
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;
|
||||
@ -1078,13 +1076,19 @@ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
|
||||
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
|
||||
@ -1423,8 +1427,10 @@ size_binop_loc (location_t loc, enum tree_code code, tree arg0, tree arg1)
|
||||
return arg1;
|
||||
}
|
||||
|
||||
/* Handle general case of two integer constants. */
|
||||
return int_const_binop (code, arg0, 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);
|
||||
@ -5908,11 +5914,9 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
|
||||
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)))
|
||||
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
|
||||
@ -9971,7 +9975,8 @@ fold_binary_loc (location_t loc,
|
||||
if (TREE_CODE (arg0) == ADDR_EXPR)
|
||||
{
|
||||
tem = try_move_mult_to_index (loc, arg0,
|
||||
fold_convert_loc (loc, sizetype, arg1));
|
||||
fold_convert_loc (loc,
|
||||
ssizetype, arg1));
|
||||
if (tem)
|
||||
return fold_convert_loc (loc, type, tem);
|
||||
}
|
||||
|
@ -336,9 +336,11 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case PLUS_EXPR:
|
||||
case POINTER_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,
|
||||
|
@ -2182,11 +2182,37 @@ layout_type (tree type)
|
||||
that (possible) negative values are handled appropriately
|
||||
when determining overflow. */
|
||||
else
|
||||
length
|
||||
= fold_convert (sizetype,
|
||||
size_binop (PLUS_EXPR,
|
||||
build_int_cst (TREE_TYPE (lb), 1),
|
||||
size_binop (MINUS_EXPR, ub, lb)));
|
||||
{
|
||||
/* ??? When it is obvious that the range is signed
|
||||
represent it using ssizetype. */
|
||||
if (TREE_CODE (lb) == INTEGER_CST
|
||||
&& TREE_CODE (ub) == INTEGER_CST
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (lb))
|
||||
&& tree_int_cst_lt (ub, lb))
|
||||
{
|
||||
lb = double_int_to_tree
|
||||
(ssizetype,
|
||||
double_int_sext (tree_to_double_int (lb),
|
||||
TYPE_PRECISION (TREE_TYPE (lb))));
|
||||
ub = double_int_to_tree
|
||||
(ssizetype,
|
||||
double_int_sext (tree_to_double_int (ub),
|
||||
TYPE_PRECISION (TREE_TYPE (ub))));
|
||||
}
|
||||
length
|
||||
= fold_convert (sizetype,
|
||||
size_binop (PLUS_EXPR,
|
||||
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,
|
||||
@ -2453,11 +2479,6 @@ initialize_sizetypes (void)
|
||||
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));
|
||||
@ -2466,11 +2487,6 @@ initialize_sizetypes (void)
|
||||
= 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));
|
||||
|
@ -1,3 +1,7 @@
|
||||
2012-05-02 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* g++.dg/tree-ssa/pr19807.C: Adjust.
|
||||
|
||||
2012-05-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/53163
|
||||
|
@ -25,6 +25,6 @@ void bar(int i)
|
||||
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 "\\\+ (0x0f*|18446744073709551615|4294967295|-1);" "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
||||
|
@ -1101,14 +1101,12 @@ bit_value_unop_1 (enum tree_code code, tree type,
|
||||
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));
|
||||
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 = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
|
||||
? 0 : TYPE_UNSIGNED (type));
|
||||
uns = TYPE_UNSIGNED (type);
|
||||
*mask = double_int_ext (*mask, TYPE_PRECISION (type), uns);
|
||||
*val = double_int_ext (*val, TYPE_PRECISION (type), uns);
|
||||
break;
|
||||
@ -1130,8 +1128,7 @@ bit_value_binop_1 (enum tree_code code, tree type,
|
||||
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));
|
||||
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;
|
||||
@ -1198,13 +1195,6 @@ bit_value_binop_1 (enum tree_code code, tree type,
|
||||
}
|
||||
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);
|
||||
@ -1316,12 +1306,7 @@ bit_value_binop_1 (enum tree_code code, tree type,
|
||||
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;
|
||||
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
|
||||
|
51
gcc/tree.c
51
gcc/tree.c
@ -1062,10 +1062,7 @@ build_int_cst_type (tree type, HOST_WIDE_INT low)
|
||||
tree
|
||||
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)));
|
||||
bool sign_extended_type = !TYPE_UNSIGNED (type);
|
||||
|
||||
cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
|
||||
|
||||
@ -1079,9 +1076,7 @@ bool
|
||||
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)));
|
||||
bool sign_extended_type = !TYPE_UNSIGNED (type);
|
||||
|
||||
double_int ext
|
||||
= double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
|
||||
@ -1111,9 +1106,7 @@ force_fit_type_double (tree type, double_int cst, int overflowable,
|
||||
bool sign_extended_type;
|
||||
|
||||
/* Size types *are* sign extended. */
|
||||
sign_extended_type = (!TYPE_UNSIGNED (type)
|
||||
|| (TREE_CODE (type) == INTEGER_TYPE
|
||||
&& TYPE_IS_SIZETYPE (type)));
|
||||
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))
|
||||
@ -6553,9 +6546,7 @@ host_integerp (const_tree t, int pos)
|
||||
&& (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)))))
|
||||
&& !TYPE_UNSIGNED (TREE_TYPE (t)))
|
||||
|| (pos && TREE_INT_CST_HIGH (t) == 0)));
|
||||
}
|
||||
|
||||
@ -6850,6 +6841,20 @@ compare_tree_int (const_tree t, unsigned HOST_WIDE_INT u)
|
||||
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
|
||||
@ -8276,18 +8281,6 @@ int_fits_type_p (const_tree c, const_tree type)
|
||||
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);
|
||||
@ -8306,10 +8299,6 @@ retry:
|
||||
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));
|
||||
@ -8331,10 +8320,6 @@ retry:
|
||||
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));
|
||||
|
@ -4451,6 +4451,7 @@ extern bool tree_expr_nonnegative_warnv_p (tree, bool *);
|
||||
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. */
|
||||
|
||||
|
@ -1992,7 +1992,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
|
||||
return;
|
||||
|
||||
if (! dont_output_data
|
||||
&& ! host_integerp (DECL_SIZE_UNIT (decl), 1))
|
||||
&& ! valid_constant_size_p (DECL_SIZE_UNIT (decl)))
|
||||
{
|
||||
error ("size of variable %q+D is too large", decl);
|
||||
return;
|
||||
@ -4773,9 +4773,13 @@ output_constructor_regular_field (oc_local_state *local)
|
||||
|
||||
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));
|
||||
gcc_assert (double_int_fits_in_shwi_p (idx));
|
||||
idx = double_int_sext (idx, prec);
|
||||
fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
|
||||
* idx.low);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user