Skip to content

Commit 5479b7c

Browse files
authored
Merge pull request diffblue#7704 from tautschnig/feature/simp-pointer-equal
Simplify equality over address-of with offset
2 parents 339505b + 7da6b86 commit 5479b7c

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
int main()
2+
{
3+
int A[2];
4+
int b;
5+
6+
int *ptr = &A[1];
7+
8+
if(ptr == &b)
9+
{
10+
__CPROVER_assert(0, "unreachable");
11+
}
12+
else if((unsigned long long)ptr == (unsigned long long)&b)
13+
{
14+
__CPROVER_assert(0, "unreachable");
15+
}
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
4+
^Generated \d+ VCC\(s\), 1 remaining after simplification$
5+
^VERIFICATION SUCCESSFUL$
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
10+
--
11+
Simplification and constant propagation make the comparison over (unrelated)
12+
pointers trivially false; the corresponding comparison over pointers cast to
13+
integers is not simplified as the simplifier need not know how pointers convert
14+
to integers (except for NULL).

src/util/simplify_expr_int.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Author: Daniel Kroening, [email protected]
2424
#include "rational_tools.h"
2525
#include "simplify_utils.h"
2626
#include "std_expr.h"
27+
#include "threeval.h"
2728

2829
#include <algorithm>
2930

@@ -1605,6 +1606,38 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_no_constant(
16051606
{
16061607
return unchanged(expr);
16071608
}
1609+
else if(
1610+
expr.id() == ID_equal && ptr_op0.id() == ID_address_of &&
1611+
ptr_op1.id() == ID_address_of)
1612+
{
1613+
// comparing pointers: if both are address-of-plus-some-constant such that
1614+
// the resulting pointer remains within object bounds then they can never
1615+
// be equal
1616+
auto in_bounds = [this](const exprt &object_ptr, const exprt &expr_op) {
1617+
auto object_size =
1618+
size_of_expr(to_address_of_expr(object_ptr).object().type(), ns);
1619+
1620+
if(object_size.has_value())
1621+
{
1622+
pointer_offset_exprt offset{expr_op, object_size->type()};
1623+
exprt in_object_bounds =
1624+
simplify_rec(binary_relation_exprt{
1625+
std::move(offset), ID_lt, std::move(*object_size)})
1626+
.expr;
1627+
if(in_object_bounds.is_constant())
1628+
return tvt{in_object_bounds.is_true()};
1629+
}
1630+
1631+
return tvt::unknown();
1632+
};
1633+
1634+
if(
1635+
in_bounds(ptr_op0, expr.op0()).is_true() &&
1636+
in_bounds(ptr_op1, expr.op1()).is_true())
1637+
{
1638+
return false_exprt{};
1639+
}
1640+
}
16081641
}
16091642

16101643
// eliminate strict inequalities

0 commit comments

Comments
 (0)