Skip to content

Commit bdbaed0

Browse files
committed
Add conversion of is_dynamic_object_exprt to SMT
This is the final step required to complete the implementation of the support for this kind of expression.
1 parent c6cfd6c commit bdbaed0

File tree

6 files changed

+82
-22
lines changed

6 files changed

+82
-22
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,11 +1042,18 @@ static smt_termt convert_expr_to_smt(
10421042

10431043
static smt_termt convert_expr_to_smt(
10441044
const is_dynamic_object_exprt &is_dynamic_object,
1045-
const sub_expression_mapt &converted)
1045+
const sub_expression_mapt &converted,
1046+
const smt_is_dynamic_objectt::make_applicationt &apply_is_dynamic_object)
10461047
{
1047-
UNIMPLEMENTED_FEATURE(
1048-
"Generation of SMT formula for is dynamic object expression: " +
1049-
is_dynamic_object.pretty());
1048+
const smt_termt &pointer = converted.at(is_dynamic_object.address());
1049+
const auto pointer_sort = pointer.get_sort().cast<smt_bit_vector_sortt>();
1050+
INVARIANT(
1051+
pointer_sort, "Pointers should be encoded as bit vector sorted terms.");
1052+
const std::size_t pointer_width = pointer_sort->bit_width();
1053+
return apply_is_dynamic_object(
1054+
std::vector<smt_termt>{smt_bit_vector_theoryt::extract(
1055+
pointer_width - 1,
1056+
pointer_width - config.bv_encoding.object_bits)(pointer)});
10501057
}
10511058

10521059
static smt_termt convert_expr_to_smt(
@@ -1458,7 +1465,8 @@ static smt_termt dispatch_expr_to_smt_conversion(
14581465
const sub_expression_mapt &converted,
14591466
const smt_object_mapt &object_map,
14601467
const type_size_mapt &pointer_sizes,
1461-
const smt_object_sizet::make_applicationt &call_object_size)
1468+
const smt_object_sizet::make_applicationt &call_object_size,
1469+
const smt_is_dynamic_objectt::make_applicationt &apply_is_dynamic_object)
14621470
{
14631471
if(const auto symbol = expr_try_dynamic_cast<symbol_exprt>(expr))
14641472
{
@@ -1660,7 +1668,8 @@ static smt_termt dispatch_expr_to_smt_conversion(
16601668
const auto is_dynamic_object =
16611669
expr_try_dynamic_cast<is_dynamic_object_exprt>(expr))
16621670
{
1663-
return convert_expr_to_smt(*is_dynamic_object, converted);
1671+
return convert_expr_to_smt(
1672+
*is_dynamic_object, converted, apply_is_dynamic_object);
16641673
}
16651674
if(
16661675
const auto is_invalid_pointer =
@@ -1837,7 +1846,8 @@ smt_termt convert_expr_to_smt(
18371846
const exprt &expr,
18381847
const smt_object_mapt &object_map,
18391848
const type_size_mapt &pointer_sizes,
1840-
const smt_object_sizet::make_applicationt &object_size)
1849+
const smt_object_sizet::make_applicationt &object_size,
1850+
const smt_is_dynamic_objectt::make_applicationt &is_dynamic_object)
18411851
{
18421852
#ifndef CPROVER_INVARIANT_DO_NOT_CHECK
18431853
static bool in_conversion = false;
@@ -1856,7 +1866,12 @@ smt_termt convert_expr_to_smt(
18561866
if(find_result != sub_expression_map.cend())
18571867
return;
18581868
smt_termt term = dispatch_expr_to_smt_conversion(
1859-
expr, sub_expression_map, object_map, pointer_sizes, object_size);
1869+
expr,
1870+
sub_expression_map,
1871+
object_map,
1872+
pointer_sizes,
1873+
object_size,
1874+
is_dynamic_object);
18601875
sub_expression_map.emplace_hint(find_result, expr, std::move(term));
18611876
});
18621877
return std::move(sub_expression_map.at(lowered_expr));

src/solvers/smt2_incremental/convert_expr_to_smt.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <solvers/smt2_incremental/ast/smt_sorts.h>
77
#include <solvers/smt2_incremental/ast/smt_terms.h>
88
#include <solvers/smt2_incremental/object_tracking.h>
9+
#include <solvers/smt2_incremental/smt_is_dynamic_object.h>
910
#include <solvers/smt2_incremental/smt_object_size.h>
1011
#include <solvers/smt2_incremental/type_size_mapping.h>
1112

@@ -27,6 +28,7 @@ smt_termt convert_expr_to_smt(
2728
const exprt &expression,
2829
const smt_object_mapt &object_map,
2930
const type_size_mapt &pointer_sizes,
30-
const smt_object_sizet::make_applicationt &object_size);
31+
const smt_object_sizet::make_applicationt &object_size,
32+
const smt_is_dynamic_objectt::make_applicationt &is_dynamic_object);
3133

3234
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_CONVERT_EXPR_TO_SMT_H

src/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,14 @@ smt2_incremental_decision_proceduret::convert_expr_to_smt(const exprt &expr)
322322
ns,
323323
pointer_sizes_map,
324324
object_map,
325-
object_size_function.make_application);
325+
object_size_function.make_application,
326+
is_dynamic_object_function.make_application);
326327
return ::convert_expr_to_smt(
327328
substituted,
328329
object_map,
329330
pointer_sizes_map,
330-
object_size_function.make_application);
331+
object_size_function.make_application,
332+
is_dynamic_object_function.make_application);
331333
}
332334

333335
exprt smt2_incremental_decision_proceduret::handle(const exprt &expr)
@@ -377,7 +379,8 @@ array_exprt smt2_incremental_decision_proceduret::get_expr(
377379
from_integer(index, index_type),
378380
object_map,
379381
pointer_sizes_map,
380-
object_size_function.make_application)),
382+
object_size_function.make_application,
383+
is_dynamic_object_function.make_application)),
381384
type.element_type()));
382385
}
383386
return array_exprt{elements, type};
@@ -443,7 +446,8 @@ exprt smt2_incremental_decision_proceduret::get(const exprt &expr) const
443446
expr,
444447
object_map,
445448
pointer_sizes_map,
446-
object_size_function.make_application);
449+
object_size_function.make_application,
450+
is_dynamic_object_function.make_application);
447451
}
448452
else
449453
{

src/solvers/smt2_incremental/type_size_mapping.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ void associate_pointer_sizes(
1515
const namespacet &ns,
1616
type_size_mapt &type_size_map,
1717
const smt_object_mapt &object_map,
18-
const smt_object_sizet::make_applicationt &object_size)
18+
const smt_object_sizet::make_applicationt &object_size,
19+
const smt_is_dynamic_objectt::make_applicationt &is_dynamic_object)
1920
{
2021
expression.visit_pre([&](const exprt &sub_expression) {
2122
if(
@@ -42,7 +43,11 @@ void associate_pointer_sizes(
4243
pointer_size_expr = pointer_size_opt.value();
4344
}
4445
auto pointer_size_term = convert_expr_to_smt(
45-
pointer_size_expr, object_map, type_size_map, object_size);
46+
pointer_size_expr,
47+
object_map,
48+
type_size_map,
49+
object_size,
50+
is_dynamic_object);
4651
type_size_map.emplace_hint(
4752
find_result, pointer_type->base_type(), pointer_size_term);
4853
}

src/solvers/smt2_incremental/type_size_mapping.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <solvers/smt2_incremental/ast/smt_terms.h>
1212
#include <solvers/smt2_incremental/object_tracking.h>
13+
#include <solvers/smt2_incremental/smt_is_dynamic_object.h>
1314
#include <solvers/smt2_incremental/smt_object_size.h>
1415

1516
#include <unordered_map>
@@ -28,11 +29,13 @@ using type_size_mapt = std::unordered_map<typet, smt_termt, irep_full_hash>;
2829
/// from \p expression which are not already keys in the map.
2930
/// \param object_map: passed through to convert_expr_to_smt
3031
/// \param object_size: passed through to convert_expr_to_smt
32+
/// \param is_dynamic_object: passed through to convert_expr_to_smt
3133
void associate_pointer_sizes(
3234
const exprt &expression,
3335
const namespacet &ns,
3436
type_size_mapt &type_size_map,
3537
const smt_object_mapt &object_map,
36-
const smt_object_sizet::make_applicationt &object_size);
38+
const smt_object_sizet::make_applicationt &object_size,
39+
const smt_is_dynamic_objectt::make_applicationt &is_dynamic_object);
3740

3841
#endif

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct expr_to_smt_conversion_test_environmentt
5959

6060
smt_object_mapt object_map;
6161
smt_object_sizet object_size_function;
62+
smt_is_dynamic_objectt is_dynamic_object_function;
6263
type_size_mapt pointer_sizes;
6364

6465
private:
@@ -94,7 +95,8 @@ expr_to_smt_conversion_test_environmentt::convert(const exprt &expression) const
9495
expression,
9596
object_map,
9697
pointer_sizes,
97-
object_size_function.make_application);
98+
object_size_function.make_application,
99+
is_dynamic_object_function.make_application);
98100
}
99101

100102
TEST_CASE("\"array_typet\" to smt sort conversion", "[core][smt2_incremental]")
@@ -471,7 +473,8 @@ TEST_CASE(
471473
ns,
472474
test.pointer_sizes,
473475
test.object_map,
474-
test.object_size_function.make_application);
476+
test.object_size_function.make_application,
477+
test.is_dynamic_object_function.make_application);
475478

476479
INFO("Input expr: " + pointer_arith_expr.pretty(2, 0));
477480
const auto constructed_term = test.convert(pointer_arith_expr);
@@ -546,7 +549,8 @@ TEST_CASE(
546549
ns,
547550
test.pointer_sizes,
548551
test.object_map,
549-
test.object_size_function.make_application);
552+
test.object_size_function.make_application,
553+
test.is_dynamic_object_function.make_application);
550554

551555
INFO("Input expr: " + pointer_arith_expr.pretty(2, 0));
552556
const auto constructed_term = test.convert(pointer_arith_expr);
@@ -577,7 +581,8 @@ TEST_CASE(
577581
ns,
578582
test.pointer_sizes,
579583
test.object_map,
580-
test.object_size_function.make_application);
584+
test.object_size_function.make_application,
585+
test.is_dynamic_object_function.make_application);
581586
INFO("Input expr: " + pointer_arith_expr.pretty(2, 0));
582587
const auto constructed_term = test.convert(pointer_arith_expr);
583588
const auto expected_term = smt_bit_vector_theoryt::subtract(
@@ -614,7 +619,8 @@ TEST_CASE(
614619
ns,
615620
test.pointer_sizes,
616621
test.object_map,
617-
test.object_size_function.make_application);
622+
test.object_size_function.make_application,
623+
test.is_dynamic_object_function.make_application);
618624
INFO("Input expr: " + pointer_subtraction.pretty(2, 0));
619625
const auto constructed_term = test.convert(pointer_subtraction);
620626
const auto expected_term = smt_bit_vector_theoryt::signed_divide(
@@ -1673,6 +1679,30 @@ TEST_CASE(
16731679
smt_bit_vector_theoryt::concat(object, offset))}));
16741680
}
16751681

1682+
TEST_CASE(
1683+
"expr to smt conversion for is_dynamic_object expressions",
1684+
"[core][smt2_incremental]")
1685+
{
1686+
auto test =
1687+
expr_to_smt_conversion_test_environmentt::make(test_archt::x86_64);
1688+
const symbol_tablet symbol_table;
1689+
const namespacet ns{symbol_table};
1690+
const symbol_exprt foo{"foo", unsignedbv_typet{32}};
1691+
const is_dynamic_object_exprt is_dynamic_object{address_of_exprt{foo}};
1692+
track_expression_objects(is_dynamic_object, ns, test.object_map);
1693+
const auto foo_id = 2;
1694+
CHECK(test.object_map.at(foo).unique_id == foo_id);
1695+
const auto object_bits = config.bv_encoding.object_bits;
1696+
const auto object = smt_bit_vector_constant_termt{foo_id, object_bits};
1697+
const auto offset = smt_bit_vector_constant_termt{0, 64 - object_bits};
1698+
INFO("Expression " + is_dynamic_object.pretty(1, 0));
1699+
CHECK(
1700+
test.convert(is_dynamic_object) ==
1701+
test.is_dynamic_object_function.make_application(std::vector<smt_termt>{
1702+
smt_bit_vector_theoryt::extract(63, 64 - object_bits)(
1703+
smt_bit_vector_theoryt::concat(object, offset))}));
1704+
}
1705+
16761706
TEST_CASE(
16771707
"lower_address_of_array_index works correctly",
16781708
"[core][smt2_incremental]")
@@ -1718,7 +1748,8 @@ TEST_CASE(
17181748
ns,
17191749
test.pointer_sizes,
17201750
test.object_map,
1721-
test.object_size_function.make_application);
1751+
test.object_size_function.make_application,
1752+
test.is_dynamic_object_function.make_application);
17221753
const smt_termt expected = smt_core_theoryt::equal(
17231754
smt_identifier_termt(symbol.get_identifier(), smt_bit_vector_sortt{64}),
17241755
smt_bit_vector_theoryt::add(

0 commit comments

Comments
 (0)