summaryrefslogtreecommitdiffstats
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 41081ff919c..fe12942d981 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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);
}
OpenPOWER on IntegriCloud