aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2005-01-08 16:13:22 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2005-01-08 16:13:22 +0000
commit4634cf7ee2a5a8a322288125746cd4c28b0dceab (patch)
tree153da8865020a4a1dbf41c9ed27dbb1b38b0cfec /gcc/tree.c
parent88c0f1c63f152af3577ed3a99f37db01995bd22d (diff)
downloadgcc-4634cf7ee2a5a8a322288125746cd4c28b0dceab.zip
gcc-4634cf7ee2a5a8a322288125746cd4c28b0dceab.tar.gz
gcc-4634cf7ee2a5a8a322288125746cd4c28b0dceab.tar.bz2
tree.c (int_fits_type_p): Always honor integer constant TYPE_MIN_VALUE and TYPE_MAX_VALUE if they exist.
* tree.c (int_fits_type_p): Always honor integer constant TYPE_MIN_VALUE and TYPE_MAX_VALUE if they exist. From-SVN: r93086
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c67
1 files changed, 33 insertions, 34 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index e648aaa..39309ff 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -4874,23 +4874,8 @@ int_fits_type_p (tree c, tree type)
{
tree type_low_bound = TYPE_MIN_VALUE (type);
tree type_high_bound = TYPE_MAX_VALUE (type);
- int ok_for_low_bound, ok_for_high_bound;
-
- /* Perform some generic filtering first, which may allow making a decision
- even if the bounds are not constant. First, negative integers never fit
- in unsigned types, */
- if (TYPE_UNSIGNED (type) && tree_int_cst_sgn (c) < 0)
- return 0;
-
- /* Second, narrower types always fit in wider ones. */
- if (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (c)))
- return 1;
-
- /* Third, unsigned integers with top bit set never fit signed types. */
- if (! TYPE_UNSIGNED (type)
- && TYPE_UNSIGNED (TREE_TYPE (c))
- && tree_int_cst_msb (c))
- return 0;
+ bool ok_for_low_bound, ok_for_high_bound;
+ tree tmp;
/* If at least one bound of the type is a constant integer, we can check
ourselves and maybe make a decision. If no such decision is possible, but
@@ -4902,43 +4887,57 @@ int_fits_type_p (tree c, tree type)
for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
for "constant known to fit". */
- ok_for_low_bound = -1;
- ok_for_high_bound = -1;
-
/* Check if C >= type_low_bound. */
if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
{
- ok_for_low_bound = ! tree_int_cst_lt (c, type_low_bound);
- if (! ok_for_low_bound)
+ if (tree_int_cst_lt (c, type_low_bound))
return 0;
+ ok_for_low_bound = true;
}
+ else
+ ok_for_low_bound = false;
/* Check if c <= type_high_bound. */
if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
{
- ok_for_high_bound = ! tree_int_cst_lt (type_high_bound, c);
- if (! ok_for_high_bound)
+ if (tree_int_cst_lt (type_high_bound, c))
return 0;
+ ok_for_high_bound = true;
}
+ else
+ ok_for_high_bound = false;
/* If the constant fits both bounds, the result is known. */
- if (ok_for_low_bound == 1 && ok_for_high_bound == 1)
+ if (ok_for_low_bound && ok_for_high_bound)
return 1;
+ /* Perform some generic filtering which may allow making a decision
+ even if the bounds are not constant. First, negative integers
+ never fit in unsigned types, */
+ if (TYPE_UNSIGNED (type) && tree_int_cst_sgn (c) < 0)
+ return 0;
+
+ /* Second, narrower types always fit in wider ones. */
+ if (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (c)))
+ return 1;
+
+ /* Third, unsigned integers with top bit set never fit signed types. */
+ if (! TYPE_UNSIGNED (type)
+ && TYPE_UNSIGNED (TREE_TYPE (c))
+ && tree_int_cst_msb (c))
+ return 0;
+
/* If we haven't been able to decide at this point, there nothing more we
can check ourselves here. Look at the base type if we have one. */
- else if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != 0)
+ if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != 0)
return int_fits_type_p (c, TREE_TYPE (type));
/* Or to force_fit_type, if nothing else. */
- else
- {
- tree n = copy_node (c);
- TREE_TYPE (n) = type;
- n = force_fit_type (n, -1, false, false);
- return TREE_INT_CST_HIGH (n) == TREE_INT_CST_HIGH (c)
- && TREE_INT_CST_LOW (n) == TREE_INT_CST_LOW (c);
- }
+ tmp = copy_node (c);
+ TREE_TYPE (tmp) = type;
+ tmp = force_fit_type (tmp, -1, false, false);
+ return TREE_INT_CST_HIGH (tmp) == TREE_INT_CST_HIGH (c)
+ && TREE_INT_CST_LOW (tmp) == TREE_INT_CST_LOW (c);
}
/* Subprogram of following function. Called by walk_tree.