Skip to content

Commit b5d2a72

Browse files
authored
Merge pull request #5922 from tautschnig/fix-5921
Use simplification for more reliable pointer comparison
2 parents ae4dca8 + 9d2ca74 commit b5d2a72

File tree

5 files changed

+45
-20
lines changed

5 files changed

+45
-20
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
int *get_ptr_minus_one(int *ptr)
5+
{
6+
if(ptr)
7+
return ptr - 1;
8+
return 0;
9+
}
10+
11+
int main()
12+
{
13+
int *begin = malloc(4 * 4);
14+
int *end = begin + 1;
15+
16+
if(begin != get_ptr_minus_one(end))
17+
assert(0);
18+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

src/goto-symex/symex_goto.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,9 @@ static optionalt<renamedt<exprt, L2>> try_evaluate_pointer_comparison(
8585
{
8686
const constant_exprt *constant_expr =
8787
expr_try_dynamic_cast<constant_exprt>(other_operand);
88-
const exprt other_without_typecast = skip_typecast(other_operand);
8988

9089
if(
91-
other_without_typecast.id() != ID_address_of &&
90+
skip_typecast(other_operand).id() != ID_address_of &&
9291
(!constant_expr || constant_expr->get_value() != ID_NULL))
9392
{
9493
return {};
@@ -129,12 +128,25 @@ static optionalt<renamedt<exprt, L2>> try_evaluate_pointer_comparison(
129128
value_set_dereferencet::build_reference_to(
130129
value_set_element, symbol_expr, ns);
131130

132-
if(skip_typecast(value.pointer) == other_without_typecast)
131+
// use the simplifier to test equality as we need to skip over typecasts
132+
// and cannot rely on canonical representations, which would permit a
133+
// simple syntactic equality test
134+
exprt test_equal = simplify_expr(
135+
equal_exprt{
136+
typecast_exprt::conditional_cast(value.pointer, other_operand.type()),
137+
other_operand},
138+
ns);
139+
if(test_equal.is_true())
133140
{
134141
constant_found = true;
135142
// We can't break because we have to make sure we find any instances of
136143
// ID_unknown or ID_invalid
137144
}
145+
else if(!test_equal.is_false())
146+
{
147+
// We can't conclude anything about the value-set
148+
return {};
149+
}
138150
}
139151
}
140152

src/util/simplify_expr_int.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,13 +1243,8 @@ simplify_exprt::simplify_inequality(const binary_relation_exprt &expr)
12431243

12441244
// see if we are comparing pointers that are address_of
12451245
if(
1246-
(tmp0.id() == ID_address_of ||
1247-
(tmp0.id() == ID_typecast &&
1248-
to_typecast_expr(tmp0).op().id() == ID_address_of)) &&
1249-
(tmp1.id() == ID_address_of ||
1250-
(tmp1.id() == ID_typecast &&
1251-
to_typecast_expr(tmp1).op().id() == ID_address_of)) &&
1252-
(expr.id() == ID_equal || expr.id() == ID_notequal))
1246+
skip_typecast(tmp0).id() == ID_address_of &&
1247+
skip_typecast(tmp1).id() == ID_address_of)
12531248
{
12541249
return simplify_inequality_address_of(expr);
12551250
}

src/util/simplify_expr_pointer.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -426,12 +426,8 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_address_of(
426426

427427
PRECONDITION(expr.id() == ID_equal || expr.id() == ID_notequal);
428428

429-
exprt tmp0=expr.op0();
430-
431429
// skip over the typecast
432-
if(tmp0.id()==ID_typecast)
433-
tmp0 = to_typecast_expr(tmp0).op();
434-
430+
exprt tmp0 = skip_typecast(expr.op0());
435431
PRECONDITION(tmp0.id() == ID_address_of);
436432

437433
auto &tmp0_address_of = to_address_of_expr(tmp0);
@@ -444,12 +440,8 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_address_of(
444440
address_of_exprt(to_index_expr(tmp0_address_of.object()).array());
445441
}
446442

447-
exprt tmp1=expr.op1();
448-
449443
// skip over the typecast
450-
if(tmp1.id()==ID_typecast)
451-
tmp1 = to_typecast_expr(tmp1).op();
452-
444+
exprt tmp1 = skip_typecast(expr.op1());
453445
PRECONDITION(tmp1.id() == ID_address_of);
454446

455447
auto &tmp1_address_of = to_address_of_expr(tmp1);

0 commit comments

Comments
 (0)