Skip to content

Commit 7bea872

Browse files
authored
Merge pull request #7341 from tautschnig/feature/simp-pointer-subtract
Simplify non-trivial pointer subtraction
2 parents 25abf15 + 633875b commit 7bea872

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

src/util/simplify_expr_int.cpp

+28-3
Original file line numberDiff line numberDiff line change
@@ -595,10 +595,35 @@ simplify_exprt::simplify_minus(const minus_exprt &expr)
595595
is_number(minus_expr.type()) && operands[0].type().id() == ID_pointer &&
596596
operands[1].type().id() == ID_pointer)
597597
{
598-
// pointer arithmetic: rewrite "p-p" to "0"
598+
exprt ptr_op0 = simplify_object(operands[0]).expr;
599+
exprt ptr_op1 = simplify_object(operands[1]).expr;
599600

600-
if(operands[0]==operands[1])
601-
return from_integer(0, minus_expr.type());
601+
auto address_of = expr_try_dynamic_cast<address_of_exprt>(ptr_op0);
602+
if(ptr_op0 == ptr_op1 && address_of)
603+
{
604+
exprt offset_op0 = simplify_pointer_offset(
605+
pointer_offset_exprt{operands[0], minus_expr.type()});
606+
exprt offset_op1 = simplify_pointer_offset(
607+
pointer_offset_exprt{operands[1], minus_expr.type()});
608+
609+
const auto object_size =
610+
pointer_offset_size(address_of->object().type(), ns);
611+
auto element_size =
612+
size_of_expr(to_pointer_type(operands[0].type()).base_type(), ns);
613+
614+
if(
615+
offset_op0.is_constant() && offset_op1.is_constant() &&
616+
object_size.has_value() && element_size.has_value() &&
617+
numeric_cast_v<mp_integer>(to_constant_expr(offset_op0)) <=
618+
*object_size &&
619+
numeric_cast_v<mp_integer>(to_constant_expr(offset_op1)) <=
620+
*object_size)
621+
{
622+
return changed(simplify_rec(div_exprt{
623+
minus_exprt{offset_op0, offset_op1},
624+
typecast_exprt{*element_size, minus_expr.type()}}));
625+
}
626+
}
602627
}
603628

604629
return unchanged(expr);

0 commit comments

Comments
 (0)