Skip to content

Commit dc91b3c

Browse files
committed
Further simplification of (in)equalities over pointers
Address-of plus offset cannot be NULL when the pointer remains within bounds; equalities when left and right sides refer to the same object can be simplified to equalities over the pointer offsets.
1 parent d932d6f commit dc91b3c

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

src/util/simplify_expr_int.cpp

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,19 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_no_constant(
15701570
new_expr.rhs() = simplify_node(new_expr.rhs());
15711571
return changed(simplify_inequality(new_expr)); // recursive call
15721572
}
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+
}
15731586
}
15741587

15751588
return unchanged(expr);
@@ -1666,17 +1679,26 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_rhs_is_constant(
16661679
}
16671680
else if(expr.op0().id() == ID_plus)
16681681
{
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))
16781693
{
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+
}
16801702
}
16811703
}
16821704
}

0 commit comments

Comments
 (0)