Skip to content

Commit afd2d09

Browse files
committed
is_invalid_pointer is now defined as a bi-implication
The previous encoding of is_invalid_pointer is an implication, which means that constraints that a pointer is not an invalid pointer have no meaning. This commit changes the encoding to be a bi-implication, using the numerical range of the valid pointers.
1 parent c3d7235 commit afd2d09

File tree

1 file changed

+23
-31
lines changed

1 file changed

+23
-31
lines changed

src/solvers/flattening/bv_pointers.cpp

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -119,37 +119,7 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
119119

120120
const exprt::operandst &operands=expr.operands();
121121

122-
if(expr.id() == ID_is_invalid_pointer)
123-
{
124-
if(operands.size()==1 &&
125-
operands[0].type().id()==ID_pointer)
126-
{
127-
const bvt &bv=convert_bv(operands[0]);
128-
129-
if(!bv.empty())
130-
{
131-
const pointer_typet &type = to_pointer_type(operands[0].type());
132-
bvt object_bv = object_literals(bv, type);
133-
134-
bvt invalid_bv = object_literals(
135-
encode(pointer_logic.get_invalid_object(), type), type);
136-
137-
const std::size_t object_bits =
138-
bv_pointers_width.get_object_width(type);
139-
140-
bvt equal_invalid_bv;
141-
equal_invalid_bv.reserve(object_bits);
142-
143-
for(std::size_t i=0; i<object_bits; i++)
144-
{
145-
equal_invalid_bv.push_back(prop.lequal(object_bv[i], invalid_bv[i]));
146-
}
147-
148-
return prop.land(equal_invalid_bv);
149-
}
150-
}
151-
}
152-
else if(expr.id() == ID_is_dynamic_object)
122+
if(expr.id() == ID_is_dynamic_object || expr.id() == ID_is_invalid_pointer)
153123
{
154124
if(operands.size()==1 &&
155125
operands[0].type().id()==ID_pointer)
@@ -910,6 +880,28 @@ void bv_pointerst::do_postponed(
910880
prop.l_set_to_true(prop.limplies(l1, l2));
911881
}
912882
}
883+
else if(postponed.expr.id() == ID_is_invalid_pointer)
884+
{
885+
const auto &type =
886+
to_pointer_type(to_unary_expr(postponed.expr).op().type());
887+
const auto &objects = pointer_logic.objects;
888+
889+
// only compare object part
890+
bvt bv = object_literals(encode(objects.size(), type), type);
891+
892+
bvt saved_bv = object_literals(postponed.op, type);
893+
894+
POSTCONDITION(bv.size() == saved_bv.size());
895+
PRECONDITION(postponed.bv.size() == 1);
896+
897+
// the pointer is invalid iff the object number is greater or
898+
// equal objects.size()
899+
literalt l1 = bv_utils.lt_or_le(
900+
true, bv, saved_bv, bv_utilst::representationt::UNSIGNED);
901+
literalt l2 = postponed.bv.front();
902+
903+
prop.l_set_to_true(prop.lequal(l1, l2));
904+
}
913905
else if(postponed.expr.id()==ID_object_size)
914906
{
915907
const auto &type =

0 commit comments

Comments
 (0)