@@ -1206,6 +1206,62 @@ void smv_typecheckt::typecheck_expr_rec(exprt &expr, modet mode)
12061206 << " abs expects integer" ;
12071207 }
12081208 }
1209+ else if (expr.id () == ID_smv_bit_selection) // word[high:low]
1210+ {
1211+ auto &op = to_ternary_expr (expr).op0 ();
1212+
1213+ typecheck_expr_rec (op, mode);
1214+
1215+ if (op.type ().id () != ID_unsignedbv && op.type ().id () != ID_signedbv)
1216+ {
1217+ throw errort ().with_location (op.source_location ())
1218+ << " bit selection expects word" ;
1219+ }
1220+
1221+ auto &high = to_ternary_expr (expr).op1 ();
1222+
1223+ typecheck_expr_rec (high, OTHER);
1224+
1225+ // high must be an integer constant
1226+ if (high.type ().id () != ID_range && high.type ().id () != ID_natural)
1227+ {
1228+ throw errort ().with_location (expr.find_source_location ())
1229+ << " bit-select high must be integer, but got "
1230+ << to_string (high.type ());
1231+ }
1232+
1233+ if (high.id () != ID_constant)
1234+ throw errort ().with_location (expr.find_source_location ())
1235+ << " bit-select high must be constant" ;
1236+
1237+ auto high_int = numeric_cast_v<mp_integer>(to_constant_expr (high));
1238+
1239+ auto &low = to_ternary_expr (expr).op2 ();
1240+
1241+ typecheck_expr_rec (low, OTHER);
1242+
1243+ // low must be an integer constant
1244+ if (low.type ().id () != ID_range && low.type ().id () != ID_natural)
1245+ {
1246+ throw errort ().with_location (expr.find_source_location ())
1247+ << " bit-select low must be integer, but got " << to_string (low.type ());
1248+ }
1249+
1250+ if (low.id () != ID_constant)
1251+ throw errort ().with_location (expr.find_source_location ())
1252+ << " bit-select low must be constant" ;
1253+
1254+ auto low_int = numeric_cast_v<mp_integer>(to_constant_expr (low));
1255+
1256+ if (low_int > high_int)
1257+ throw errort ().with_location (expr.find_source_location ())
1258+ << " bit-select high must not be smaller than low" ;
1259+
1260+ auto width = numeric_cast_v<std::size_t >(high_int - low_int + 1 );
1261+
1262+ // always unsigned, even if op is signed
1263+ expr.type () = unsignedbv_typet{width};
1264+ }
12091265 else if (expr.id () == ID_smv_bool)
12101266 {
12111267 auto &op = to_unary_expr (expr).op ();
@@ -1626,6 +1682,13 @@ void smv_typecheckt::lower_node(exprt &expr) const
16261682 auto &implies = to_smv_bitimplies_expr (expr);
16271683 expr = bitor_exprt{bitnot_exprt{implies.op0 ()}, implies.op1 ()};
16281684 }
1685+ else if (expr.id () == ID_smv_bit_selection)
1686+ {
1687+ // we'll lower to extractbits
1688+ auto &bit_selection = to_ternary_expr (expr);
1689+ expr = extractbits_exprt{
1690+ bit_selection.op0 (), bit_selection.op2 (), bit_selection.type ()};
1691+ }
16291692
16301693 // lower the type
16311694 lower (expr.type ());
0 commit comments