@@ -833,6 +833,127 @@ static smt_termt convert_expr_to_smt(const isnormal_exprt &is_normal_expr)
833
833
is_normal_expr.pretty ());
834
834
}
835
835
836
+ // / \brief
837
+ // / Constructs a term which is true if the most significant bit of \p input
838
+ // / is set.
839
+ static smt_termt most_significant_bit_is_set (const smt_termt &input)
840
+ {
841
+ const auto bit_vector_sort = input.get_sort ().cast <smt_bit_vector_sortt>();
842
+ INVARIANT (
843
+ bit_vector_sort,
844
+ " Most significant bit can only be extracted from bit vector terms." );
845
+ const size_t most_significant_bit_index = bit_vector_sort->bit_width () - 1 ;
846
+ const auto extract_most_significant_bit = smt_bit_vector_theoryt::extract (
847
+ most_significant_bit_index, most_significant_bit_index);
848
+ return smt_core_theoryt::equal (
849
+ extract_most_significant_bit (input), smt_bit_vector_constant_termt{1 , 1 });
850
+ }
851
+
852
+ static smt_termt convert_expr_to_smt (const plus_overflow_exprt &plus_overflow)
853
+ {
854
+ const smt_termt left = convert_expr_to_smt (plus_overflow.lhs ());
855
+ const smt_termt right = convert_expr_to_smt (plus_overflow.rhs ());
856
+ if (operands_are_of_type<unsignedbv_typet>(plus_overflow))
857
+ {
858
+ const auto add_carry_bit = smt_bit_vector_theoryt::zero_extend (1 );
859
+ return most_significant_bit_is_set (
860
+ smt_bit_vector_theoryt::add (add_carry_bit (left), add_carry_bit (right)));
861
+ }
862
+ if (operands_are_of_type<signedbv_typet>(plus_overflow))
863
+ {
864
+ // Overflow has occurred if the operands have the same sign and adding them
865
+ // gives a result of the opposite sign.
866
+ const smt_termt msb_left = most_significant_bit_is_set (left);
867
+ const smt_termt msb_right = most_significant_bit_is_set (right);
868
+ return smt_core_theoryt::make_and (
869
+ smt_core_theoryt::equal (msb_left, msb_right),
870
+ smt_core_theoryt::distinct (
871
+ msb_left,
872
+ most_significant_bit_is_set (smt_bit_vector_theoryt::add (left, right))));
873
+ }
874
+ UNIMPLEMENTED_FEATURE (
875
+ " Generation of SMT formula for plus overflow expression: " +
876
+ plus_overflow.pretty ());
877
+ }
878
+
879
+ static smt_termt convert_expr_to_smt (const minus_overflow_exprt &minus_overflow)
880
+ {
881
+ const smt_termt left = convert_expr_to_smt (minus_overflow.lhs ());
882
+ const smt_termt right = convert_expr_to_smt (minus_overflow.rhs ());
883
+ if (operands_are_of_type<unsignedbv_typet>(minus_overflow))
884
+ {
885
+ return smt_bit_vector_theoryt::unsigned_less_than (left, right);
886
+ }
887
+ if (operands_are_of_type<signedbv_typet>(minus_overflow))
888
+ {
889
+ // Overflow has occurred if the operands have the opposing signs and
890
+ // subtracting them gives a result having the same signedness as the
891
+ // right-hand operand. For example the following would be overflow for cases
892
+ // for 8 bit wide bit vectors -
893
+ // -128 - 1 == 127
894
+ // 127 - (-1) == -128
895
+ const smt_termt msb_left = most_significant_bit_is_set (left);
896
+ const smt_termt msb_right = most_significant_bit_is_set (right);
897
+ return smt_core_theoryt::make_and (
898
+ smt_core_theoryt::distinct (msb_left, msb_right),
899
+ smt_core_theoryt::equal (
900
+ msb_right,
901
+ most_significant_bit_is_set (
902
+ smt_bit_vector_theoryt::subtract (left, right))));
903
+ }
904
+ UNIMPLEMENTED_FEATURE (
905
+ " Generation of SMT formula for minus overflow expression: " +
906
+ minus_overflow.pretty ());
907
+ }
908
+
909
+ static smt_termt convert_expr_to_smt (const mult_overflow_exprt &mult_overflow)
910
+ {
911
+ PRECONDITION (mult_overflow.lhs ().type () == mult_overflow.rhs ().type ());
912
+ const auto &operand_type = mult_overflow.lhs ().type ();
913
+ const smt_termt left = convert_expr_to_smt (mult_overflow.lhs ());
914
+ const smt_termt right = convert_expr_to_smt (mult_overflow.rhs ());
915
+ if (
916
+ const auto unsigned_type =
917
+ type_try_dynamic_cast<unsignedbv_typet>(operand_type))
918
+ {
919
+ const std::size_t width = unsigned_type->get_width ();
920
+ const auto extend = smt_bit_vector_theoryt::zero_extend (width);
921
+ return smt_bit_vector_theoryt::unsigned_greater_than_or_equal (
922
+ smt_bit_vector_theoryt::multiply (extend (left), extend (right)),
923
+ smt_bit_vector_constant_termt{power (2 , width), width * 2 });
924
+ }
925
+ if (
926
+ const auto signed_type =
927
+ type_try_dynamic_cast<signedbv_typet>(operand_type))
928
+ {
929
+ const smt_termt msb_left = most_significant_bit_is_set (left);
930
+ const smt_termt msb_right = most_significant_bit_is_set (right);
931
+ const std::size_t width = signed_type->get_width ();
932
+ const auto extend = smt_bit_vector_theoryt::sign_extend (width);
933
+ const auto multiplication =
934
+ smt_bit_vector_theoryt::multiply (extend (left), extend (right));
935
+ const auto too_large = smt_bit_vector_theoryt::signed_greater_than_or_equal (
936
+ multiplication,
937
+ smt_bit_vector_constant_termt{power (2 , width - 1 ), width * 2 });
938
+ const auto too_small = smt_bit_vector_theoryt::signed_less_than (
939
+ multiplication,
940
+ smt_bit_vector_theoryt::negate (
941
+ smt_bit_vector_constant_termt{power (2 , width - 1 ), width * 2 }));
942
+ return smt_core_theoryt::if_then_else (
943
+ smt_core_theoryt::equal (msb_left, msb_right), too_large, too_small);
944
+ }
945
+ UNIMPLEMENTED_FEATURE (
946
+ " Generation of SMT formula for multiply overflow expression: " +
947
+ mult_overflow.pretty ());
948
+ }
949
+
950
+ static smt_termt convert_expr_to_smt (const shl_overflow_exprt &shl_overflow)
951
+ {
952
+ UNIMPLEMENTED_FEATURE (
953
+ " Generation of SMT formula for shift left overflow expression: " +
954
+ shl_overflow.pretty ());
955
+ }
956
+
836
957
static smt_termt convert_expr_to_smt (const array_exprt &array_construction)
837
958
{
838
959
UNIMPLEMENTED_FEATURE (
@@ -1144,6 +1265,26 @@ smt_termt convert_expr_to_smt(const exprt &expr)
1144
1265
{
1145
1266
return convert_expr_to_smt (*is_normal_expr);
1146
1267
}
1268
+ if (
1269
+ const auto plus_overflow = expr_try_dynamic_cast<plus_overflow_exprt>(expr))
1270
+ {
1271
+ return convert_expr_to_smt (*plus_overflow);
1272
+ }
1273
+ if (
1274
+ const auto minus_overflow =
1275
+ expr_try_dynamic_cast<minus_overflow_exprt>(expr))
1276
+ {
1277
+ return convert_expr_to_smt (*minus_overflow);
1278
+ }
1279
+ if (
1280
+ const auto mult_overflow = expr_try_dynamic_cast<mult_overflow_exprt>(expr))
1281
+ {
1282
+ return convert_expr_to_smt (*mult_overflow);
1283
+ }
1284
+ if (const auto shl_overflow = expr_try_dynamic_cast<shl_overflow_exprt>(expr))
1285
+ {
1286
+ return convert_expr_to_smt (*shl_overflow);
1287
+ }
1147
1288
if (const auto array_construction = expr_try_dynamic_cast<array_exprt>(expr))
1148
1289
{
1149
1290
return convert_expr_to_smt (*array_construction);
0 commit comments