Skip to content

Commit a209b44

Browse files
authored
Merge pull request #8466 from diffblue/smt2-range
SMT2: implement range type
2 parents d2b4455 + e21c686 commit a209b44

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

src/solvers/smt2/smt2_conv.cpp

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ exprt smt2_convt::parse_rec(const irept &src, const typet &type)
723723
type.id() == ID_integer || type.id() == ID_rational ||
724724
type.id() == ID_real || type.id() == ID_c_enum ||
725725
type.id() == ID_c_enum_tag || type.id() == ID_fixedbv ||
726-
type.id() == ID_floatbv || type.id() == ID_c_bool)
726+
type.id() == ID_floatbv || type.id() == ID_c_bool || type.id() == ID_range)
727727
{
728728
return parse_literal(src, type);
729729
}
@@ -2920,7 +2920,35 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
29202920
}
29212921
else if(dest_type.id()==ID_range)
29222922
{
2923-
SMT2_TODO("range typecast");
2923+
auto &dest_range_type = to_range_type(dest_type);
2924+
const auto dest_size =
2925+
dest_range_type.get_to() - dest_range_type.get_from() + 1;
2926+
const auto dest_width = address_bits(dest_size);
2927+
if(src_type.id() == ID_range)
2928+
{
2929+
auto &src_range_type = to_range_type(src_type);
2930+
const auto src_size =
2931+
src_range_type.get_to() - src_range_type.get_from() + 1;
2932+
const auto src_width = address_bits(src_size);
2933+
if(src_width < dest_width)
2934+
{
2935+
out << "((_ zero_extend " << dest_width - src_width << ") ";
2936+
convert_expr(src);
2937+
out << ')'; // zero_extend
2938+
}
2939+
else if(src_width > dest_width)
2940+
{
2941+
out << "((_ extract " << dest_width - 1 << " 0) ";
2942+
convert_expr(src);
2943+
out << ')'; // extract
2944+
}
2945+
else // src_width == dest_width
2946+
{
2947+
convert_expr(src);
2948+
}
2949+
}
2950+
else
2951+
SMT2_TODO("typecast from " + src_type.id_string() + " to range");
29242952
}
29252953
else if(dest_type.id()==ID_floatbv)
29262954
{
@@ -3440,6 +3468,15 @@ void smt2_convt::convert_constant(const constant_exprt &expr)
34403468
else
34413469
out << value;
34423470
}
3471+
else if(expr_type.id() == ID_range)
3472+
{
3473+
auto &range_type = to_range_type(expr_type);
3474+
const auto size = range_type.get_to() - range_type.get_from() + 1;
3475+
const auto width = address_bits(size);
3476+
const auto value_int = numeric_cast_v<mp_integer>(expr);
3477+
out << "(_ bv" << (value_int - range_type.get_from()) << " " << width
3478+
<< ")";
3479+
}
34433480
else
34443481
UNEXPECTEDCASE("unknown constant: "+expr_type.id_string());
34453482
}
@@ -3641,7 +3678,7 @@ void smt2_convt::convert_plus(const plus_exprt &expr)
36413678
}
36423679
else if(
36433680
expr.type().id() == ID_unsignedbv || expr.type().id() == ID_signedbv ||
3644-
expr.type().id() == ID_fixedbv)
3681+
expr.type().id() == ID_fixedbv || expr.type().id() == ID_range)
36453682
{
36463683
// These could be chained, i.e., need not be binary,
36473684
// but at least MathSat doesn't like that.
@@ -5601,6 +5638,14 @@ void smt2_convt::convert_type(const typet &type)
56015638
{
56025639
out << "state";
56035640
}
5641+
else if(type.id() == ID_range)
5642+
{
5643+
auto &range_type = to_range_type(type);
5644+
mp_integer size = range_type.get_to() - range_type.get_from() + 1;
5645+
if(size <= 0)
5646+
UNEXPECTEDCASE("unsuppored range type");
5647+
out << "(_ BitVec " << address_bits(size) << ")";
5648+
}
56045649
else
56055650
{
56065651
UNEXPECTEDCASE("unsupported type: "+type.id_string());

0 commit comments

Comments
 (0)