Skip to content

Commit 37a8720

Browse files
authored
Merge pull request #3646 from diffblue/smt2-tag-types
SMT2: convert struct_tag and union_tag types
2 parents d11ec53 + 170c522 commit 37a8720

File tree

1 file changed

+52
-26
lines changed

1 file changed

+52
-26
lines changed

src/solvers/smt2/smt2_conv.cpp

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -556,10 +556,10 @@ void smt2_convt::convert_address_of_rec(
556556
const typet &struct_op_type=ns.follow(struct_op.type());
557557

558558
DATA_INVARIANT(
559-
struct_op_type.id() == ID_struct,
559+
struct_op_type.id() == ID_struct || struct_op_type.id() == ID_struct_tag,
560560
"member expression operand shall have struct type");
561561

562-
const struct_typet &struct_type = to_struct_type(struct_op_type);
562+
const struct_typet &struct_type = to_struct_type(ns.follow(struct_op_type));
563563

564564
const irep_idt &component_name = member_expr.get_component_name();
565565

@@ -2140,7 +2140,9 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
21402140
else
21412141
SMT2_TODO("can't convert non-constant integer to bitvector");
21422142
}
2143-
else if(src_type.id()==ID_struct) // flatten a struct to a bit-vector
2143+
else if(
2144+
src_type.id() == ID_struct ||
2145+
src_type.id() == ID_struct_tag) // flatten a struct to a bit-vector
21442146
{
21452147
if(use_datatypes)
21462148
{
@@ -2157,7 +2159,9 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
21572159
convert_expr(src); // nothing else to do!
21582160
}
21592161
}
2160-
else if(src_type.id()==ID_union) // flatten a union
2162+
else if(
2163+
src_type.id() == ID_union ||
2164+
src_type.id() == ID_union_tag) // flatten a union
21612165
{
21622166
INVARIANT(
21632167
boolbv_width(src_type) == boolbv_width(dest_type),
@@ -2570,7 +2574,7 @@ void smt2_convt::convert_floatbv_typecast(const floatbv_typecast_exprt &expr)
25702574

25712575
void smt2_convt::convert_struct(const struct_exprt &expr)
25722576
{
2573-
const struct_typet &struct_type=to_struct_type(expr.type());
2577+
const struct_typet &struct_type = to_struct_type(ns.follow(expr.type()));
25742578

25752579
const struct_typet::componentst &components=
25762580
struct_type.components();
@@ -2664,7 +2668,7 @@ void smt2_convt::flatten_array(const exprt &expr)
26642668

26652669
void smt2_convt::convert_union(const union_exprt &expr)
26662670
{
2667-
const union_typet &union_type=to_union_type(expr.type());
2671+
const union_typet &union_type = to_union_type(ns.follow(expr.type()));
26682672
const exprt &op=expr.op();
26692673

26702674
boolbv_widtht boolbv_width(ns);
@@ -3552,9 +3556,9 @@ void smt2_convt::convert_with(const with_exprt &expr)
35523556
out << ") distance?)))"; // zero_extend, bvshl, bvor, let
35533557
}
35543558
}
3555-
else if(expr_type.id()==ID_struct)
3559+
else if(expr_type.id() == ID_struct || expr_type.id() == ID_struct_tag)
35563560
{
3557-
const struct_typet &struct_type=to_struct_type(expr_type);
3561+
const struct_typet &struct_type = to_struct_type(ns.follow(expr_type));
35583562

35593563
const exprt &index=expr.op1();
35603564
const exprt &value=expr.op2();
@@ -3623,9 +3627,9 @@ void smt2_convt::convert_with(const with_exprt &expr)
36233627
out << ")"; // let ?withop
36243628
}
36253629
}
3626-
else if(expr_type.id()==ID_union)
3630+
else if(expr_type.id() == ID_union || expr_type.id() == ID_union_tag)
36273631
{
3628-
const union_typet &union_type=to_union_type(expr_type);
3632+
const union_typet &union_type = to_union_type(ns.follow(expr_type));
36293633

36303634
const exprt &value=expr.op2();
36313635

@@ -3829,10 +3833,9 @@ void smt2_convt::convert_member(const member_exprt &expr)
38293833
const typet &struct_op_type=ns.follow(struct_op.type());
38303834
const irep_idt &name=member_expr.get_component_name();
38313835

3832-
if(struct_op_type.id()==ID_struct)
3836+
if(struct_op_type.id() == ID_struct || struct_op_type.id() == ID_struct_tag)
38333837
{
3834-
const struct_typet &struct_type=
3835-
to_struct_type(struct_op_type);
3838+
const struct_typet &struct_type = to_struct_type(ns.follow(struct_op_type));
38363839

38373840
INVARIANT(
38383841
struct_type.has_component(name), "struct should have accessed component");
@@ -3862,7 +3865,8 @@ void smt2_convt::convert_member(const member_exprt &expr)
38623865
out << ")";
38633866
}
38643867
}
3865-
else if(struct_op_type.id()==ID_union)
3868+
else if(
3869+
struct_op_type.id() == ID_union || struct_op_type.id() == ID_union_tag)
38663870
{
38673871
std::size_t width=boolbv_width(expr.type());
38683872
CHECK_RETURN_WITH_DIAGNOSTICS(
@@ -3924,14 +3928,14 @@ void smt2_convt::flatten2bv(const exprt &expr)
39243928
{
39253929
convert_expr(expr);
39263930
}
3927-
else if(type.id()==ID_struct)
3931+
else if(type.id() == ID_struct || type.id() == ID_struct_tag)
39283932
{
39293933
if(use_datatypes)
39303934
{
39313935
const std::string &smt_typename = datatype_map.at(type);
39323936

39333937
// concatenate elements
3934-
const struct_typet &struct_type=to_struct_type(type);
3938+
const struct_typet &struct_type = to_struct_type(ns.follow(type));
39353939

39363940
out << "(let ((?sflop ";
39373941
convert_expr(expr);
@@ -4027,7 +4031,7 @@ void smt2_convt::unflatten(
40274031
// nop, already a bv
40284032
}
40294033
}
4030-
else if(type.id()==ID_struct)
4034+
else if(type.id() == ID_struct || type.id() == ID_struct_tag)
40314035
{
40324036
if(use_datatypes)
40334037
{
@@ -4042,7 +4046,7 @@ void smt2_convt::unflatten(
40424046

40434047
out << "(mk-" << smt_typename;
40444048

4045-
const struct_typet &struct_type=to_struct_type(type);
4049+
const struct_typet &struct_type = to_struct_type(ns.follow(type));
40464050

40474051
const struct_typet::componentst &components=
40484052
struct_type.components();
@@ -4426,7 +4430,7 @@ void smt2_convt::convert_type(const typet &type)
44264430
{
44274431
out << "Bool";
44284432
}
4429-
else if(type.id()==ID_struct)
4433+
else if(type.id() == ID_struct || type.id() == ID_struct_tag)
44304434
{
44314435
if(use_datatypes)
44324436
{
@@ -4465,7 +4469,7 @@ void smt2_convt::convert_type(const typet &type)
44654469
// member count.
44664470
out << "Bool";
44674471
}
4468-
else if(type.id()==ID_union)
4472+
else if(type.id() == ID_union || type.id() == ID_union_tag)
44694473
{
44704474
boolbv_widtht boolbv_width(ns);
44714475

@@ -4617,7 +4621,7 @@ void smt2_convt::find_symbols_rec(
46174621
out << "))))\n";
46184622
}
46194623
}
4620-
else if(type.id()==ID_struct)
4624+
else if(type.id() == ID_struct)
46214625
{
46224626
// Cater for mutually recursive struct types
46234627
bool need_decl=false;
@@ -4630,11 +4634,11 @@ void smt2_convt::find_symbols_rec(
46304634
need_decl=true;
46314635
}
46324636

4633-
const struct_typet::componentst &components=
4637+
const struct_typet::componentst &components =
46344638
to_struct_type(type).components();
46354639

4636-
for(const auto &component : components)
4637-
find_symbols_rec(component.type(), recstack);
4640+
for(const auto &component : components)
4641+
find_symbols_rec(component.type(), recstack);
46384642

46394643
// Declare the corresponding SMT type if we haven't already.
46404644
if(need_decl)
@@ -4713,9 +4717,9 @@ void smt2_convt::find_symbols_rec(
47134717
out << "\n";
47144718
}
47154719
}
4716-
else if(type.id()==ID_union)
4720+
else if(type.id() == ID_union)
47174721
{
4718-
const union_typet::componentst &components=
4722+
const union_typet::componentst &components =
47194723
to_union_type(type).components();
47204724

47214725
for(const auto &component : components)
@@ -4745,6 +4749,28 @@ void smt2_convt::find_symbols_rec(
47454749
find_symbols_rec(ns.follow(type), recstack);
47464750
}
47474751
}
4752+
else if(type.id() == ID_struct_tag)
4753+
{
4754+
const auto &struct_tag = to_struct_tag_type(type);
4755+
const irep_idt &id = struct_tag.get_identifier();
4756+
4757+
if(recstack.find(id) == recstack.end())
4758+
{
4759+
recstack.insert(id);
4760+
find_symbols_rec(ns.follow_tag(struct_tag), recstack);
4761+
}
4762+
}
4763+
else if(type.id() == ID_union_tag)
4764+
{
4765+
const auto &union_tag = to_union_tag_type(type);
4766+
const irep_idt &id = union_tag.get_identifier();
4767+
4768+
if(recstack.find(id) == recstack.end())
4769+
{
4770+
recstack.insert(id);
4771+
find_symbols_rec(ns.follow_tag(union_tag), recstack);
4772+
}
4773+
}
47484774
}
47494775

47504776
exprt smt2_convt::letify(exprt &expr)

0 commit comments

Comments
 (0)