Skip to content

Commit 8c7ef17

Browse files
committed
Try to keep struct and SMTLIB data types in sync
1 parent 9efd7a4 commit 8c7ef17

File tree

1 file changed

+38
-19
lines changed

1 file changed

+38
-19
lines changed

src/solvers/smt2/smt2_conv.cpp

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -612,21 +612,14 @@ smt2_convt::parse_struct(const irept &src, const struct_typet &type)
612612
{
613613
// Structs look like:
614614
// (mk-struct.1 <component0> <component1> ... <componentN>)
615-
std::size_t j = 1;
615+
616+
if(src.get_sub().size()!=components.size()+1)
617+
return result; // give up
618+
616619
for(std::size_t i=0; i<components.size(); i++)
617620
{
618621
const struct_typet::componentt &c=components[i];
619-
if(is_zero_width(components[i].type(), ns))
620-
{
621-
result.operands()[i] = nil_exprt{};
622-
}
623-
else
624-
{
625-
DATA_INVARIANT(
626-
src.get_sub().size() > j, "insufficient number of component values");
627-
result.operands()[i] = parse_rec(src.get_sub()[j], c.type());
628-
++j;
629-
}
622+
result.operands()[i]=parse_rec(src.get_sub()[i+1], c.type());
630623
}
631624
}
632625
else
@@ -3225,8 +3218,6 @@ void smt2_convt::convert_struct(const struct_exprt &expr)
32253218
"number of struct components as indicated by the struct type shall be equal"
32263219
"to the number of operands of the struct expression");
32273220

3228-
DATA_INVARIANT(!components.empty(), "struct shall have struct components");
3229-
32303221
if(use_datatypes)
32313222
{
32323223
const std::string &smt_typename = datatype_map.at(struct_type);
@@ -3240,16 +3231,29 @@ void smt2_convt::convert_struct(const struct_exprt &expr)
32403231
it!=components.end();
32413232
it++, i++)
32423233
{
3243-
if(is_zero_width(it->type(), ns))
3234+
if(
3235+
it->type().id() != ID_struct_tag && it->type().id() != ID_struct &&
3236+
is_zero_width(it->type(), ns))
3237+
{
32443238
continue;
3239+
}
3240+
32453241
out << " ";
32463242
convert_expr(expr.operands()[i]);
32473243
}
32483244

3245+
if(components.empty())
3246+
{
3247+
out << " ";
3248+
convert_expr(from_integer(0, unsignedbv_typet{1}));
3249+
}
3250+
32493251
out << ")";
32503252
}
32513253
else
32523254
{
3255+
DATA_INVARIANT(!components.empty(), "struct shall have struct components");
3256+
32533257
if(components.size()==1)
32543258
{
32553259
const exprt &op = expr.op0();
@@ -4903,9 +4907,6 @@ void smt2_convt::unflatten(
49034907
it!=components.end();
49044908
it++, i++)
49054909
{
4906-
if(is_zero_width(it->type(), ns))
4907-
continue;
4908-
49094910
std::size_t member_width=boolbv_width(it->type());
49104911

49114912
out << " ";
@@ -4916,6 +4917,12 @@ void smt2_convt::unflatten(
49164917
offset+=member_width;
49174918
}
49184919

4920+
if(components.empty())
4921+
{
4922+
out << " ";
4923+
convert_expr(from_integer(0, unsignedbv_typet{1}));
4924+
}
4925+
49194926
out << "))"; // mk-, let
49204927
}
49214928
}
@@ -5940,15 +5947,27 @@ void smt2_convt::find_symbols_rec(
59405947

59415948
for(const auto &component : components)
59425949
{
5943-
if(is_zero_width(component.type(), ns))
5950+
if(
5951+
component.type().id() != ID_struct_tag &&
5952+
component.type().id() != ID_struct &&
5953+
is_zero_width(component.type(), ns))
5954+
{
59445955
continue;
5956+
}
59455957

59465958
out << "(" << smt_typename << "." << component.get_name()
59475959
<< " ";
59485960
convert_type(component.type());
59495961
out << ") ";
59505962
}
59515963

5964+
if(components.empty())
5965+
{
5966+
out << "(" << smt_typename << ".0 ";
5967+
convert_type(unsignedbv_typet{1});
5968+
out << ") ";
5969+
}
5970+
59525971
out << "))))" << "\n";
59535972

59545973
// Let's also declare convenience functions to update individual

0 commit comments

Comments
 (0)