https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108647
--- Comment #12 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #7)
> So
> --- gcc/range-op.cc.jj 2023-02-03 10:51:40.699003658 +0100
> +++ gcc/range-op.cc 2023-02-03 16:04:39.264159294 +0100
> @@ -642,7 +642,8 @@ operator_equal::op1_range (irange &r, tr
> case BRS_FALSE:
> // If the result is false, the only time we know anything is
> // if OP2 is a constant.
> - if (wi::eq_p (op2.lower_bound(), op2.upper_bound()))
> + if (!op2.undefined_p ()
> + && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
> {
> r = op2;
> r.invert ();
> @@ -755,7 +756,8 @@ operator_not_equal::op1_range (irange &r
> case BRS_TRUE:
> // If the result is true, the only time we know anything is if
> // OP2 is a constant.
> - if (wi::eq_p (op2.lower_bound(), op2.upper_bound()))
> + if (!op2.undefined_p ()
> + && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
> {
> r = op2;
> r.invert ();
> @@ -920,6 +922,9 @@ operator_lt::op1_range (irange &r, tree
> const irange &op2,
> relation_trio) const
> {
> + if (op2.undefined_p ())
> + return false;
> +
> switch (get_bool_state (r, lhs, type))
> {
> case BRS_TRUE:
> @@ -942,6 +947,9 @@ operator_lt::op2_range (irange &r, tree
> const irange &op1,
> relation_trio) const
> {
> + if (op1.undefined_p ())
> + return false;
> +
> switch (get_bool_state (r, lhs, type))
> {
> case BRS_TRUE:
> @@ -1031,6 +1039,9 @@ operator_le::op1_range (irange &r, tree
> const irange &op2,
> relation_trio) const
> {
> + if (op2.undefined_p ())
> + return false;
> +
> switch (get_bool_state (r, lhs, type))
> {
> case BRS_TRUE:
> @@ -1053,6 +1064,9 @@ operator_le::op2_range (irange &r, tree
> const irange &op1,
> relation_trio) const
> {
> + if (op1.undefined_p ())
> + return false;
> +
> switch (get_bool_state (r, lhs, type))
> {
> case BRS_TRUE:
> @@ -1141,6 +1155,9 @@ operator_gt::op1_range (irange &r, tree
> const irange &lhs, const irange &op2,
> relation_trio) const
> {
> + if (op2.undefined_p ())
> + return false;
> +
> switch (get_bool_state (r, lhs, type))
> {
> case BRS_TRUE:
> @@ -1163,6 +1180,9 @@ operator_gt::op2_range (irange &r, tree
> const irange &op1,
> relation_trio) const
> {
> + if (op1.undefined_p ())
> + return false;
> +
> switch (get_bool_state (r, lhs, type))
> {
> case BRS_TRUE:
> @@ -1252,6 +1272,9 @@ operator_ge::op1_range (irange &r, tree
> const irange &op2,
> relation_trio) const
> {
> + if (op2.undefined_p ())
> + return false;
> +
> switch (get_bool_state (r, lhs, type))
> {
> case BRS_TRUE:
> @@ -1274,6 +1297,9 @@ operator_ge::op2_range (irange &r, tree
> const irange &op1,
> relation_trio) const
> {
> + if (op1.undefined_p ())
> + return false;
> +
> switch (get_bool_state (r, lhs, type))
> {
> case BRS_TRUE:
> then plus testcase?
Looks good to me.
Do you mind adding this bit to your testing?
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 136b709385c..fdc0a6c05fd 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2678,7 +2678,6 @@ operator_cast::op1_range (irange &r, tree type,
if (lhs.undefined_p ())
return false;
tree lhs_type = lhs.type ();
- gcc_checking_assert (types_compatible_p (op2.type(), type));
// If we are calculating a pointer, shortcut to what we really care about.
if (POINTER_TYPE_P (type))
@@ -2705,6 +2704,8 @@ operator_cast::op1_range (irange &r, tree type,
return true;
}
+ if (op2.undefined_p ())
+ return false;
if (truncating_cast_p (op2, lhs))
{
if (lhs.varying_p ())
This catches the cast operator which will ICE in truncating_cast_p when op2 is
undefined.
I've removed the checking assert since any number of operations further down
will ICE if the types don't match.