@@ -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