aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorAnatoly Sokolov <aesok@post.ru>2010-06-28 22:23:16 +0400
committerAnatoly Sokolov <aesok@gcc.gnu.org>2010-06-28 22:23:16 +0400
commit9589f23ea556ef4d3b083a83e49156780b6b9cde (patch)
tree4667776860379c311babeb25f863259e7d46dbc0 /gcc/tree.c
parentdfecaf599b25b0335a01a640821046564d0fa3f3 (diff)
downloadgcc-9589f23ea556ef4d3b083a83e49156780b6b9cde.zip
gcc-9589f23ea556ef4d3b083a83e49156780b6b9cde.tar.gz
gcc-9589f23ea556ef4d3b083a83e49156780b6b9cde.tar.bz2
double-int.h (force_fit_type_double): Remove declaration.
* double-int.h (force_fit_type_double): Remove declaration. * double-int.c (force_fit_type_double): Move to tree.c. * tree.h (force_fit_type_double): Declare. * tree.h (force_fit_type_double): Moved from double-int.c. Use double_int type for 'cst' argument. Use double_int_fits_to_tree_p and double_int_to_tree instead of fit_double_type and build_int_cst_wide. * convert.c (convert_to_pointer): Adjust call to force_fit_type_double. * tree-vrp.c (extract_range_from_assert, extract_range_from_unary_expr): Adjust call to force_fit_type_double. * fold-const.c: Update comment. (int_const_binop, fold_convert_const_int_from_int, fold_convert_const_int_from_real, fold_convert_const_int_from_fixed, extract_muldiv_1, fold_div_compare, fold_sign_changed_comparison, fold_unary_loc, fold_negate_const, fold_abs_const, fold_not_const, round_up_loc): Adjust call to force_fit_type_double. /c-family * c-common.c (shorten_compare): Adjust call to force_fit_type_double. From-SVN: r161509
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 5e7de01..de83e64 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1092,6 +1092,52 @@ double_int_fits_to_tree_p (const_tree type, double_int cst)
return double_int_equal_p (cst, ext);
}
+/* We force the double_int CST to the range of the type TYPE by sign or
+ zero extending it. OVERFLOWABLE indicates if we are interested in
+ overflow of the value, when >0 we are only interested in signed
+ overflow, for <0 we are interested in any overflow. OVERFLOWED
+ indicates whether overflow has already occurred. CONST_OVERFLOWED
+ indicates whether constant overflow has already occurred. We force
+ T's value to be within range of T's type (by setting to 0 or 1 all
+ the bits outside the type's range). We set TREE_OVERFLOWED if,
+ OVERFLOWED is nonzero,
+ or OVERFLOWABLE is >0 and signed overflow occurs
+ or OVERFLOWABLE is <0 and any overflow occurs
+ We return a new tree node for the extended double_int. The node
+ is shared if no overflow flags are set. */
+
+
+tree
+force_fit_type_double (tree type, double_int cst, int overflowable,
+ bool overflowed)
+{
+ 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))
+ {
+ if (overflowed
+ || overflowable < 0
+ || (overflowable > 0 && sign_extended_type))
+ {
+ tree t = make_node (INTEGER_CST);
+ TREE_INT_CST (t) = double_int_ext (cst, TYPE_PRECISION (type),
+ !sign_extended_type);
+ TREE_TYPE (t) = type;
+ TREE_OVERFLOW (t) = 1;
+ return t;
+ }
+ }
+
+ /* Else build a shared node. */
+ return double_int_to_tree (type, cst);
+}
+
/* These are the hash table functions for the hash table of INTEGER_CST
nodes of a sizetype. */