@@ -723,7 +723,7 @@ exprt smt2_convt::parse_rec(const irept &src, const typet &type)
723
723
type.id () == ID_integer || type.id () == ID_rational ||
724
724
type.id () == ID_real || type.id () == ID_c_enum ||
725
725
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 )
727
727
{
728
728
return parse_literal (src, type);
729
729
}
@@ -2920,7 +2920,35 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
2920
2920
}
2921
2921
else if (dest_type.id ()==ID_range)
2922
2922
{
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" );
2924
2952
}
2925
2953
else if (dest_type.id ()==ID_floatbv)
2926
2954
{
@@ -3440,6 +3468,15 @@ void smt2_convt::convert_constant(const constant_exprt &expr)
3440
3468
else
3441
3469
out << value;
3442
3470
}
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
+ }
3443
3480
else
3444
3481
UNEXPECTEDCASE (" unknown constant: " +expr_type.id_string ());
3445
3482
}
@@ -3641,7 +3678,7 @@ void smt2_convt::convert_plus(const plus_exprt &expr)
3641
3678
}
3642
3679
else if (
3643
3680
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 )
3645
3682
{
3646
3683
// These could be chained, i.e., need not be binary,
3647
3684
// but at least MathSat doesn't like that.
@@ -5601,6 +5638,14 @@ void smt2_convt::convert_type(const typet &type)
5601
5638
{
5602
5639
out << " state" ;
5603
5640
}
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
+ }
5604
5649
else
5605
5650
{
5606
5651
UNEXPECTEDCASE (" unsupported type: " +type.id_string ());
0 commit comments