Skip to content

Commit 459dd62

Browse files
authored
Merge pull request diffblue#7223 from tautschnig/bugfixes/7185-empty-compound
SMT2 back-end: support empty compound types
2 parents 6b6dae6 + c3d954e commit 459dd62

File tree

5 files changed

+68
-43
lines changed

5 files changed

+68
-43
lines changed

regression/cbmc/Empty_struct1/test.desc

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

44
^EXIT=0$

regression/cbmc/empty_compound_type2/test.desc

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

regression/cbmc/empty_compound_type3/test.desc

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

44
^EXIT=10$

regression/cbmc/empty_compound_type4/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
main.c
33
--trace
44
^VERIFICATION FAILED$

src/solvers/smt2/smt2_conv.cpp

Lines changed: 64 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,23 @@ std::string smt2_convt::convert_identifier(const irep_idt &identifier)
958958
return result;
959959
}
960960

961+
/// Returns true iff \p type has effective width of zero bits.
962+
static bool is_zero_width(const typet &type, const namespacet &ns)
963+
{
964+
if(type.id() == ID_empty)
965+
return true;
966+
else if(type.id() == ID_struct_tag)
967+
return is_zero_width(ns.follow_tag(to_struct_tag_type(type)), ns);
968+
else if(type.id() == ID_struct)
969+
return to_struct_type(type).components().empty();
970+
else if(type.id() == ID_union_tag)
971+
return is_zero_width(ns.follow_tag(to_union_tag_type(type)), ns);
972+
else if(type.id() == ID_union)
973+
return to_union_type(type).components().empty();
974+
else
975+
return false;
976+
}
977+
961978
std::string smt2_convt::type2id(const typet &type) const
962979
{
963980
if(type.id()==ID_floatbv)
@@ -1365,11 +1382,18 @@ void smt2_convt::convert_expr(const exprt &expr)
13651382
equal_expr.op0().type() == equal_expr.op1().type(),
13661383
"operands of equal expression shall have same type");
13671384

1368-
out << "(= ";
1369-
convert_expr(equal_expr.op0());
1370-
out << " ";
1371-
convert_expr(equal_expr.op1());
1372-
out << ")";
1385+
if(is_zero_width(equal_expr.lhs().type(), ns))
1386+
{
1387+
convert_expr(true_exprt());
1388+
}
1389+
else
1390+
{
1391+
out << "(= ";
1392+
convert_expr(equal_expr.op0());
1393+
out << " ";
1394+
convert_expr(equal_expr.op1());
1395+
out << ")";
1396+
}
13731397
}
13741398
else if(expr.id() == ID_notequal)
13751399
{
@@ -2369,10 +2393,6 @@ void smt2_convt::convert_expr(const exprt &expr)
23692393
{
23702394
convert_expr(simplify_expr(to_find_first_set_expr(expr).lower(), ns));
23712395
}
2372-
else if(expr.id() == ID_empty_union)
2373-
{
2374-
out << "()";
2375-
}
23762396
else if(expr.id() == ID_bitreverse)
23772397
{
23782398
convert_expr(simplify_expr(to_bitreverse_expr(expr).lower(), ns));
@@ -3597,7 +3617,7 @@ void smt2_convt::convert_plus(const plus_exprt &expr)
35973617
else
35983618
{
35993619
auto element_size_opt = pointer_offset_size(base_type, ns);
3600-
CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 1);
3620+
CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 0);
36013621
element_size = *element_size_opt;
36023622
}
36033623

@@ -4701,9 +4721,7 @@ void smt2_convt::set_to(const exprt &expr, bool value)
47014721
if(expr.id() == ID_equal && value)
47024722
{
47034723
const equal_exprt &equal_expr=to_equal_expr(expr);
4704-
if(
4705-
equal_expr.lhs().type().id() == ID_empty ||
4706-
equal_expr.rhs().id() == ID_empty_union)
4724+
if(is_zero_width(equal_expr.lhs().type(), ns))
47074725
{
47084726
// ignore equality checking over expressions with empty (void) type
47094727
return;
@@ -4955,21 +4973,24 @@ void smt2_convt::find_symbols(const exprt &expr)
49554973
convert_type(array_type);
49564974
out << ")\n";
49574975

4958-
// use a quantifier-based initialization instead of lambda
4959-
out << "(assert (forall ((i ";
4960-
convert_type(array_type.index_type());
4961-
out << ")) (= (select " << id << " i) ";
4962-
if(array_type.element_type().id() == ID_bool && !use_array_of_bool)
4976+
if(!is_zero_width(array_type.element_type(), ns))
49634977
{
4964-
out << "(ite ";
4965-
convert_expr(array_of.what());
4966-
out << " #b1 #b0)";
4967-
}
4968-
else
4969-
{
4970-
convert_expr(array_of.what());
4978+
// use a quantifier-based initialization instead of lambda
4979+
out << "(assert (forall ((i ";
4980+
convert_type(array_type.index_type());
4981+
out << ")) (= (select " << id << " i) ";
4982+
if(array_type.element_type().id() == ID_bool && !use_array_of_bool)
4983+
{
4984+
out << "(ite ";
4985+
convert_expr(array_of.what());
4986+
out << " #b1 #b0)";
4987+
}
4988+
else
4989+
{
4990+
convert_expr(array_of.what());
4991+
}
4992+
out << ")))\n";
49714993
}
4972-
out << ")))\n";
49734994

49744995
defined_expressions[expr] = id;
49754996
}
@@ -5035,22 +5056,26 @@ void smt2_convt::find_symbols(const exprt &expr)
50355056
convert_type(array_type);
50365057
out << ")" << "\n";
50375058

5038-
for(std::size_t i=0; i<expr.operands().size(); i++)
5059+
if(!is_zero_width(array_type.element_type(), ns))
50395060
{
5040-
out << "(assert (= (select " << id << " ";
5041-
convert_expr(from_integer(i, array_type.index_type()));
5042-
out << ") "; // select
5043-
if(array_type.element_type().id() == ID_bool && !use_array_of_bool)
5044-
{
5045-
out << "(ite ";
5046-
convert_expr(expr.operands()[i]);
5047-
out << " #b1 #b0)";
5048-
}
5049-
else
5061+
for(std::size_t i = 0; i < expr.operands().size(); i++)
50505062
{
5051-
convert_expr(expr.operands()[i]);
5063+
out << "(assert (= (select " << id << " ";
5064+
convert_expr(from_integer(i, array_type.index_type()));
5065+
out << ") "; // select
5066+
if(array_type.element_type().id() == ID_bool && !use_array_of_bool)
5067+
{
5068+
out << "(ite ";
5069+
convert_expr(expr.operands()[i]);
5070+
out << " #b1 #b0)";
5071+
}
5072+
else
5073+
{
5074+
convert_expr(expr.operands()[i]);
5075+
}
5076+
out << "))"
5077+
<< "\n"; // =, assert
50525078
}
5053-
out << "))" << "\n"; // =, assert
50545079
}
50555080

50565081
defined_expressions[expr]=id;

0 commit comments

Comments
 (0)