|
24 | 24 | #include "rational_tools.h"
|
25 | 25 | #include "simplify_utils.h"
|
26 | 26 | #include "std_expr.h"
|
| 27 | +#include "threeval.h" |
27 | 28 |
|
28 | 29 | #include <algorithm>
|
29 | 30 |
|
@@ -1605,6 +1606,38 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_no_constant(
|
1605 | 1606 | {
|
1606 | 1607 | return unchanged(expr);
|
1607 | 1608 | }
|
| 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 | + } |
1608 | 1641 | }
|
1609 | 1642 |
|
1610 | 1643 | // eliminate strict inequalities
|
|
0 commit comments