Skip to content

Commit d212c21

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 c588225 commit d212c21

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
@@ -1617,6 +1617,19 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_no_constant(
16171617
new_expr.rhs() = simplify_node(new_expr.rhs());
16181618
return changed(simplify_inequality(new_expr)); // recursive call
16191619
}
1620+
else if(expr.op0().type().id() == ID_pointer)
1621+
{
1622+
exprt ptr_op0 = simplify_object(expr.op0()).expr;
1623+
exprt ptr_op1 = simplify_object(expr.op1()).expr;
1624+
1625+
if(ptr_op0 == ptr_op1)
1626+
{
1627+
pointer_offset_exprt offset_op0{expr.op0(), size_type()};
1628+
pointer_offset_exprt offset_op1{expr.op1(), size_type()};
1629+
1630+
return changed(simplify_rec(equal_exprt{offset_op0, offset_op1}));
1631+
}
1632+
}
16201633
}
16211634

16221635
return unchanged(expr);
@@ -1713,17 +1726,26 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_rhs_is_constant(
17131726
}
17141727
else if(expr.op0().id() == ID_plus)
17151728
{
1716-
// NULL + 1 == NULL is false
1717-
const plus_exprt &plus = to_plus_expr(expr.op0());
1718-
if(
1719-
plus.operands().size() == 2 && plus.op0().is_constant() &&
1720-
plus.op1().is_constant() &&
1721-
((is_null_pointer(to_constant_expr(plus.op0())) &&
1722-
!plus.op1().is_zero()) ||
1723-
(is_null_pointer(to_constant_expr(plus.op1())) &&
1724-
!plus.op0().is_zero())))
1729+
exprt offset =
1730+
simplify_rec(pointer_offset_exprt{expr.op0(), size_type()}).expr;
1731+
if(!offset.is_constant())
1732+
return unchanged(expr);
1733+
1734+
exprt ptr = simplify_object(expr.op0()).expr;
1735+
// NULL + N == NULL is N == 0
1736+
if(ptr.is_constant() && is_null_pointer(to_constant_expr(ptr)))
1737+
return make_boolean_expr(offset.is_zero());
1738+
// &x + N == NULL is false when the offset is in bounds
1739+
else if(auto address_of = expr_try_dynamic_cast<address_of_exprt>(ptr))
17251740
{
1726-
return false_exprt();
1741+
const auto object_size =
1742+
pointer_offset_size(address_of->object().type(), ns);
1743+
if(
1744+
object_size.has_value() &&
1745+
numeric_cast_v<mp_integer>(to_constant_expr(offset)) < *object_size)
1746+
{
1747+
return false_exprt();
1748+
}
17271749
}
17281750
}
17291751
}

0 commit comments

Comments
 (0)