@@ -1570,6 +1570,19 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_no_constant(
1570
1570
new_expr.rhs () = simplify_node (new_expr.rhs ());
1571
1571
return changed (simplify_inequality (new_expr)); // recursive call
1572
1572
}
1573
+ else if (expr.op0 ().type ().id () == ID_pointer)
1574
+ {
1575
+ exprt ptr_op0 = simplify_object (expr.op0 ()).expr ;
1576
+ exprt ptr_op1 = simplify_object (expr.op1 ()).expr ;
1577
+
1578
+ if (ptr_op0 == ptr_op1)
1579
+ {
1580
+ pointer_offset_exprt offset_op0{expr.op0 (), size_type ()};
1581
+ pointer_offset_exprt offset_op1{expr.op1 (), size_type ()};
1582
+
1583
+ return changed (simplify_rec (equal_exprt{offset_op0, offset_op1}));
1584
+ }
1585
+ }
1573
1586
}
1574
1587
1575
1588
return unchanged (expr);
@@ -1666,17 +1679,26 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_rhs_is_constant(
1666
1679
}
1667
1680
else if (expr.op0 ().id () == ID_plus)
1668
1681
{
1669
- // NULL + 1 == NULL is false
1670
- const plus_exprt &plus = to_plus_expr (expr.op0 ());
1671
- if (
1672
- plus.operands ().size () == 2 && plus.op0 ().is_constant () &&
1673
- plus.op1 ().is_constant () &&
1674
- ((is_null_pointer (to_constant_expr (plus.op0 ())) &&
1675
- !plus.op1 ().is_zero ()) ||
1676
- (is_null_pointer (to_constant_expr (plus.op1 ())) &&
1677
- !plus.op0 ().is_zero ())))
1682
+ exprt offset =
1683
+ simplify_rec (pointer_offset_exprt{expr.op0 (), size_type ()}).expr ;
1684
+ if (!offset.is_constant ())
1685
+ return unchanged (expr);
1686
+
1687
+ exprt ptr = simplify_object (expr.op0 ()).expr ;
1688
+ // NULL + N == NULL is N == 0
1689
+ if (ptr.is_constant () && is_null_pointer (to_constant_expr (ptr)))
1690
+ return make_boolean_expr (offset.is_zero ());
1691
+ // &x + N == NULL is false when the offset is in bounds
1692
+ else if (auto address_of = expr_try_dynamic_cast<address_of_exprt>(ptr))
1678
1693
{
1679
- return false_exprt ();
1694
+ const auto object_size =
1695
+ pointer_offset_size (address_of->object ().type (), ns);
1696
+ if (
1697
+ object_size.has_value () &&
1698
+ numeric_cast_v<mp_integer>(to_constant_expr (offset)) < *object_size)
1699
+ {
1700
+ return false_exprt ();
1701
+ }
1680
1702
}
1681
1703
}
1682
1704
}
0 commit comments