Skip to content

Commit 7866f27

Browse files
author
Enrico Steffinlongo
authored
Merge pull request #7090 from esteffin/esteffin/address-of-array-index
Add address_of(array[index]) support to incremental SMT2 backend
2 parents 4e907dd + 022f674 commit 7866f27

File tree

11 files changed

+111
-8
lines changed

11 files changed

+111
-8
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
int main()
2+
{
3+
int example_array[10000];
4+
__CPROVER_assert(
5+
__CPROVER_OBJECT_SIZE(example_array) == 40000, "Array condition 1");
6+
__CPROVER_assert(
7+
__CPROVER_OBJECT_SIZE(example_array) == 40001, "Array condition 2");
8+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
array_address_of.c
3+
4+
Passing problem to incremental SMT2 solving
5+
line \d+ Array condition 1: SUCCESS
6+
line \d+ Array condition 2: FAILURE
7+
^EXIT=10$
8+
^SIGNAL=0$
9+
--
10+
--
11+
Test of getting the size of an array resulting in a address_of(array[0]) expression.

regression/cbmc-primitives/exists_assume_6231/test2.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE new-smt-backend
22
test2.c
33
--pointer-check
44
^EXIT=10$

regression/cbmc-primitives/implication_statement_checks_1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE new-smt-backend
22
--div-by-zero-check
33
test.c
44
^EXIT=0$

regression/cbmc-primitives/r_w_ok_valid/test-no-cp.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE new-smt-backend
22
main.c
33
--pointer-check --no-simplify --no-propagation
44
^EXIT=0$

regression/cbmc-primitives/same-object-01/test-no-cp.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE new-smt-backend
22
main.c
33
--no-simplify --no-propagation
44
^EXIT=0$

regression/cbmc-primitives/same-object-02/test-no-cp.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE new-smt-backend
22
main.c
33
--no-simplify --no-propagation
44
^EXIT=0$

regression/cbmc-primitives/same-object-04/test-no-cp.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE new-smt-backend
22
main.c
33
--no-simplify --no-propagation
44
^EXIT=0$

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,6 +1813,25 @@ at_scope_exitt<functiont> at_scope_exit(functiont exit_function)
18131813
}
18141814
#endif
18151815

1816+
exprt lower_address_of_array_index(exprt expr)
1817+
{
1818+
expr.visit_pre([](exprt &expr) {
1819+
const auto address_of_expr = expr_try_dynamic_cast<address_of_exprt>(expr);
1820+
if(!address_of_expr)
1821+
return;
1822+
const auto array_index_expr =
1823+
expr_try_dynamic_cast<index_exprt>(address_of_expr->object());
1824+
if(!array_index_expr)
1825+
return;
1826+
expr = plus_exprt{
1827+
address_of_exprt{
1828+
array_index_expr->array(),
1829+
type_checked_cast<pointer_typet>(address_of_expr->type())},
1830+
array_index_expr->index()};
1831+
});
1832+
return expr;
1833+
}
1834+
18161835
smt_termt convert_expr_to_smt(
18171836
const exprt &expr,
18181837
const smt_object_mapt &object_map,
@@ -1830,13 +1849,14 @@ smt_termt convert_expr_to_smt(
18301849
const auto end_conversion = at_scope_exit([&]() { in_conversion = false; });
18311850
#endif
18321851
sub_expression_mapt sub_expression_map;
1833-
expr.visit_post([&](const exprt &expr) {
1852+
const auto lowered_expr = lower_address_of_array_index(expr);
1853+
lowered_expr.visit_post([&](const exprt &expr) {
18341854
const auto find_result = sub_expression_map.find(expr);
18351855
if(find_result != sub_expression_map.cend())
18361856
return;
18371857
smt_termt term = dispatch_expr_to_smt_conversion(
18381858
expr, sub_expression_map, object_map, pointer_sizes, object_size);
18391859
sub_expression_map.emplace_hint(find_result, expr, std::move(term));
18401860
});
1841-
return std::move(sub_expression_map.at(expr));
1861+
return std::move(sub_expression_map.at(lowered_expr));
18421862
}

src/solvers/smt2_incremental/convert_expr_to_smt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ class typet;
1616
/// stored as sort ast (abstract syntax tree).
1717
smt_sortt convert_type_to_smt_sort(const typet &type);
1818

19+
/// \brief Lower the `address_of(array[idx])` sub expressions in \p expr to
20+
/// `idx + address_of(array)`, so that it can be fed to
21+
/// `convert_expr_to_smt`.
22+
exprt lower_address_of_array_index(exprt expr);
23+
1924
/// \brief Converts the \p expression to an smt encoding of the same expression
2025
/// stored as term ast (abstract syntax tree).
2126
smt_termt convert_expr_to_smt(

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,3 +1590,62 @@ TEST_CASE(
15901590
smt_bit_vector_theoryt::extract(63, 64 - object_bits)(
15911591
smt_bit_vector_theoryt::concat(object, offset))}));
15921592
}
1593+
1594+
TEST_CASE(
1595+
"lower_address_of_array_index works correctly",
1596+
"[core][smt2_incremental]")
1597+
{
1598+
auto test =
1599+
expr_to_smt_conversion_test_environmentt::make(test_archt::x86_64);
1600+
const symbol_tablet symbol_table;
1601+
const namespacet ns{symbol_table};
1602+
const typet value_type = signedbv_typet{8};
1603+
const exprt array = symbol_exprt{
1604+
"my_array", array_typet{value_type, from_integer(10, signed_size_type())}};
1605+
const exprt index = from_integer(42, unsignedbv_typet{64});
1606+
const index_exprt index_expr{array, index};
1607+
const address_of_exprt address_of_expr{index_expr};
1608+
const plus_exprt lowered{
1609+
address_of_exprt{
1610+
array, type_checked_cast<pointer_typet>(address_of_expr.type())},
1611+
index};
1612+
SECTION("Lowering address_of(array[idx])")
1613+
{
1614+
CHECK(lower_address_of_array_index(address_of_expr) == lowered);
1615+
}
1616+
SECTION("Lowering expression containing address_of(array[idx])")
1617+
{
1618+
const symbol_exprt symbol{"a_symbol", address_of_expr.type()};
1619+
const equal_exprt assignment{symbol, address_of_expr};
1620+
const equal_exprt expected{symbol, lowered};
1621+
CHECK(lower_address_of_array_index(assignment) == expected);
1622+
}
1623+
SECTION("Lowering does not lower other expressions")
1624+
{
1625+
const symbol_exprt symbol{"a_symbol", index_expr.type()};
1626+
const equal_exprt assignment{symbol, index_expr};
1627+
CHECK(lower_address_of_array_index(assignment) == assignment);
1628+
}
1629+
SECTION("Lowering is done during convert_to_smt")
1630+
{
1631+
const symbol_exprt symbol{"a_symbol", address_of_expr.type()};
1632+
const equal_exprt assignment{symbol, address_of_expr};
1633+
track_expression_objects(assignment, ns, test.object_map);
1634+
associate_pointer_sizes(
1635+
assignment,
1636+
ns,
1637+
test.pointer_sizes,
1638+
test.object_map,
1639+
test.object_size_function.make_application);
1640+
const smt_termt expected = smt_core_theoryt::equal(
1641+
smt_identifier_termt(symbol.get_identifier(), smt_bit_vector_sortt{64}),
1642+
smt_bit_vector_theoryt::add(
1643+
smt_bit_vector_theoryt::concat(
1644+
smt_bit_vector_constant_termt{2, 8},
1645+
smt_bit_vector_constant_termt{0, 56}),
1646+
smt_bit_vector_theoryt::multiply(
1647+
smt_bit_vector_constant_termt{42, 64},
1648+
smt_bit_vector_constant_termt{1, 64})));
1649+
CHECK(test.convert(assignment) == expected);
1650+
}
1651+
}

0 commit comments

Comments
 (0)