Skip to content

Commit b2e3d09

Browse files
committed
SMT back-end: flatten2bv must recurse into arrays and structs
The previous code would only work when array elements/struct members were bitvectors already. This is not true for nested compound types.
1 parent 7e8ecdc commit b2e3d09

File tree

2 files changed

+15
-23
lines changed

2 files changed

+15
-23
lines changed

regression/cbmc/field-sensitivity16/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-z3-smt-backend
1+
CORE
22
main.c
33

44
^VERIFICATION SUCCESSFUL$

src/solvers/smt2/smt2_conv.cpp

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4691,20 +4691,22 @@ void smt2_convt::flatten2bv(const exprt &expr)
46914691
mp_integer size =
46924692
numeric_cast_v<mp_integer>(to_constant_expr(array_type.size()));
46934693

4694-
out << "(let ((?aflop ";
4695-
convert_expr(expr);
4696-
out << ")) ";
4694+
// SMT-LIB 2 concat is binary only
4695+
std::size_t n_concat = 0;
4696+
for(mp_integer i = size; i > 1; --i)
4697+
{
4698+
++n_concat;
4699+
out << "(concat ";
46974700

4698-
out << "(concat";
4701+
flatten2bv(
4702+
index_exprt{expr, from_integer(i - 1, array_type.index_type())});
46994703

4700-
for(mp_integer i = 0; i != size; ++i)
4701-
{
4702-
out << " (select ?aflop ";
4703-
convert_expr(from_integer(i, array_type.index_type()));
4704-
out << ')';
4704+
out << " ";
47054705
}
47064706

4707-
out << "))"; // concat, let
4707+
flatten2bv(index_exprt{expr, from_integer(0, array_type.index_type())});
4708+
4709+
out << std::string(n_concat, ')'); // concat
47084710
}
47094711
else
47104712
convert_expr(expr);
@@ -4713,15 +4715,9 @@ void smt2_convt::flatten2bv(const exprt &expr)
47134715
{
47144716
if(use_datatypes)
47154717
{
4716-
const std::string &smt_typename = datatype_map.at(type);
4717-
47184718
// concatenate elements
47194719
const struct_typet &struct_type = to_struct_type(ns.follow(type));
47204720

4721-
out << "(let ((?sflop ";
4722-
convert_expr(expr);
4723-
out << ")) ";
4724-
47254721
const struct_typet::componentst &components=
47264722
struct_type.components();
47274723

@@ -4737,21 +4733,17 @@ void smt2_convt::flatten2bv(const exprt &expr)
47374733
out << "(concat ";
47384734
}
47394735

4740-
out << "(" << smt_typename << "." << components[i - 1].get_name()
4741-
<< " ?sflop)";
4736+
flatten2bv(member_exprt{expr, components[i - 1]});
47424737

47434738
out << " ";
47444739
}
47454740

47464741
if(!is_zero_width(components[0].type(), ns))
47474742
{
4748-
out << "(" << smt_typename << "." << components[0].get_name()
4749-
<< " ?sflop)";
4743+
flatten2bv(member_exprt{expr, components[0]});
47504744
}
47514745

47524746
out << std::string(n_concat, ')'); // concat
4753-
4754-
out << ")"; // let
47554747
}
47564748
else
47574749
convert_expr(expr);

0 commit comments

Comments
 (0)