determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]). */
if (POINTER_TYPE_P (type))
{
- if (CONVERT_EXPR_CODE_P (code))
- {
- if (range_is_nonnull (&vr0))
- set_value_range_to_nonnull (vr, type);
- else if (range_is_null (&vr0))
- set_value_range_to_null (vr, type);
- else
- set_value_range_to_varying (vr);
- }
+ if (range_is_nonnull (&vr0))
+ set_value_range_to_nonnull (vr, type);
+ else if (range_is_null (&vr0))
+ set_value_range_to_null (vr, type);
else
set_value_range_to_varying (vr);
return;
TYPE_UNSIGNED (TREE_TYPE (middleop)));
middlemax = double_int_ext (innermax, TYPE_PRECISION (TREE_TYPE (middleop)),
TYPE_UNSIGNED (TREE_TYPE (middleop)));
- /* If the middle values do not represent a proper range fail. */
- if (double_int_cmp (middlemin, middlemax,
- TYPE_UNSIGNED (TREE_TYPE (middleop))) > 0)
+ /* If the middle values are not equal to the original values fail.
+ But only if the inner cast truncates (thus we ignore differences
+ in extension to handle the case going from a range to an anti-range
+ and back). */
+ if ((TYPE_PRECISION (TREE_TYPE (innerop))
+ > TYPE_PRECISION (TREE_TYPE (middleop)))
+ && (!double_int_equal_p (innermin, middlemin)
+ || !double_int_equal_p (innermax, middlemax)))
return false;
+ /* Require that the final conversion applied to both the original
+ and the intermediate range produces the same result. */
if (!double_int_equal_p (double_int_ext (middlemin,
TYPE_PRECISION (finaltype),
TYPE_UNSIGNED (finaltype)),