Skip to content

Commit 1fe3e99

Browse files
committed
Handle infinity in the back-end and in the simplifier
We need to support at least object_size operations over infinity in the back-end as the postponed evaluation iterates over all objects, which may include ones that have infinite size.
1 parent ec66d39 commit 1fe3e99

File tree

6 files changed

+68
-1
lines changed

6 files changed

+68
-1
lines changed

Diff for: regression/cbmc/infinity1/main.c

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int A[__CPROVER_constant_infinity_uint];
2+
3+
int main()
4+
{
5+
__CPROVER_assert(__CPROVER_OBJECT_SIZE(A) > 0, "infinity is positive");
6+
}

Diff for: regression/cbmc/infinity1/test.desc

+8
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

Diff for: src/solvers/flattening/bv_pointers.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -941,9 +941,17 @@ void bv_pointerst::do_postponed(
941941
if(!size_expr.has_value())
942942
continue;
943943

944-
const exprt object_size = typecast_exprt::conditional_cast(
944+
exprt object_size = typecast_exprt::conditional_cast(
945945
size_expr.value(), postponed_object_size->type());
946946

947+
if(
948+
size_expr->id() == ID_infinity &&
949+
can_cast_type<integer_bitvector_typet>(object_size.type()))
950+
{
951+
object_size = to_integer_bitvector_type(postponed_object_size->type())
952+
.largest_expr();
953+
}
954+
947955
// only compare object part
948956
pointer_typet pt = pointer_type(expr.type());
949957
bvt bv = object_literals(encode(number, pt), type);

Diff for: src/solvers/smt2/smt2_conv.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,12 @@ void smt2_convt::define_object_size(
245245
{
246246
const typet &type = o.type();
247247
auto size_expr = size_of_expr(type, ns);
248+
if(
249+
size_expr.has_value() && size_expr->id() == ID_infinity &&
250+
can_cast_type<integer_bitvector_typet>(expr.type()))
251+
{
252+
size_expr = to_integer_bitvector_type(expr.type()).largest_expr();
253+
}
248254
const auto object_size =
249255
numeric_cast<mp_integer>(size_expr.value_or(nil_exprt()));
250256

@@ -4962,6 +4968,12 @@ void smt2_convt::find_symbols(const exprt &expr)
49624968
convert_type(object_size->type());
49634969
out << ")"
49644970
<< "\n";
4971+
out << "(declare-fun |op_" << id << "| () ";
4972+
convert_type(object_size->op().type());
4973+
out << ")\n";
4974+
out << "(assert (= |op_" << id << "| ";
4975+
convert_expr(object_size->op());
4976+
out << "))\n";
49654977

49664978
object_sizes[*object_size] = id;
49674979
}

Diff for: src/util/pointer_offset_size.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ optionalt<exprt> size_of_expr(const typet &type, const namespacet &ns)
300300

301301
if(size.is_nil())
302302
return {};
303+
else if(size.id() == ID_infinity)
304+
return infinity_exprt{sub.value().type()};
303305

304306
const auto size_casted =
305307
typecast_exprt::conditional_cast(size, sub.value().type());

Diff for: src/util/simplify_expr_int.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,29 @@ simplify_exprt::simplify_inequality(const binary_relation_exprt &expr)
12631263
return simplify_inequality_pointer_object(expr);
12641264
}
12651265

1266+
if(tmp0.id() == ID_infinity)
1267+
{
1268+
if(expr.id() == ID_ge)
1269+
return true_exprt{};
1270+
else if(expr.id() == ID_gt)
1271+
return changed(simplify_inequality(notequal_exprt{tmp0, tmp1}));
1272+
else if(expr.id() == ID_le)
1273+
return changed(simplify_inequality(equal_exprt{tmp0, tmp1}));
1274+
else if(expr.id() == ID_lt)
1275+
return false_exprt{};
1276+
}
1277+
else if(tmp1.id() == ID_infinity)
1278+
{
1279+
if(expr.id() == ID_ge)
1280+
return changed(simplify_inequality(equal_exprt{tmp0, tmp1}));
1281+
else if(expr.id() == ID_gt)
1282+
return false_exprt{};
1283+
else if(expr.id() == ID_le)
1284+
return true_exprt{};
1285+
else if(expr.id() == ID_lt)
1286+
return changed(simplify_inequality(notequal_exprt{tmp0, tmp1}));
1287+
}
1288+
12661289
if(tmp0.type().id()==ID_c_enum_tag)
12671290
tmp0.type()=ns.follow_tag(to_c_enum_tag_type(tmp0.type()));
12681291

@@ -1568,6 +1591,14 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_rhs_is_constant(
15681591
return changed(simplify_if(if_expr));
15691592
}
15701593

1594+
if(expr.op0().id() == ID_infinity)
1595+
{
1596+
if(expr.id() == ID_equal)
1597+
return false_exprt{};
1598+
else if(expr.id() == ID_notequal)
1599+
return true_exprt{};
1600+
}
1601+
15711602
// do we deal with pointers?
15721603
if(expr.op1().type().id()==ID_pointer)
15731604
{

0 commit comments

Comments
 (0)