File tree Expand file tree Collapse file tree 5 files changed +73
-2
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental Expand file tree Collapse file tree 5 files changed +73
-2
lines changed Original file line number Diff line number Diff line change @@ -365,10 +365,22 @@ static smt_termt convert_expr_to_smt(const div_exprt ÷)
365365 can_cast_type<integer_bitvector_typet>(divide.lhs ().type ()) &&
366366 can_cast_type<integer_bitvector_typet>(divide.rhs ().type ());
367367
368+ const bool both_operands_unsigned =
369+ can_cast_type<unsignedbv_typet>(divide.lhs ().type ()) &&
370+ can_cast_type<unsignedbv_typet>(divide.rhs ().type ());
371+
368372 if (both_operands_bitvector)
369373 {
370- return smt_bit_vector_theoryt::unsigned_divide (
371- convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
374+ if (both_operands_unsigned)
375+ {
376+ return smt_bit_vector_theoryt::unsigned_divide (
377+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
378+ }
379+ else
380+ {
381+ return smt_bit_vector_theoryt::signed_divide (
382+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
383+ }
372384 }
373385 else
374386 {
Original file line number Diff line number Diff line change @@ -296,3 +296,26 @@ void smt_bit_vector_theoryt::unsigned_dividet::validate(
296296const smt_function_application_termt::factoryt<
297297 smt_bit_vector_theoryt::unsigned_dividet>
298298 smt_bit_vector_theoryt::unsigned_divide{};
299+
300+ const char *smt_bit_vector_theoryt::signed_dividet::identifier ()
301+ {
302+ return " bvsdiv" ;
303+ }
304+
305+ smt_sortt smt_bit_vector_theoryt::signed_dividet::return_sort (
306+ const smt_termt &lhs,
307+ const smt_termt &rhs)
308+ {
309+ return lhs.get_sort ();
310+ }
311+
312+ void smt_bit_vector_theoryt::signed_dividet::validate (
313+ const smt_termt &lhs,
314+ const smt_termt &rhs)
315+ {
316+ validate_bit_vector_predicate_arguments (lhs, rhs);
317+ }
318+
319+ const smt_function_application_termt::factoryt<
320+ smt_bit_vector_theoryt::signed_dividet>
321+ smt_bit_vector_theoryt::signed_divide{};
Original file line number Diff line number Diff line change @@ -117,6 +117,15 @@ class smt_bit_vector_theoryt
117117 };
118118 static const smt_function_application_termt::factoryt<unsigned_dividet>
119119 unsigned_divide;
120+
121+ struct signed_dividet final
122+ {
123+ static const char *identifier ();
124+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
125+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
126+ };
127+ static const smt_function_application_termt::factoryt<signed_dividet>
128+ signed_divide;
120129};
121130
122131#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -350,11 +350,19 @@ TEST_CASE(
350350 // truncates over zero)
351351 SECTION (" Division of two constant size bit-vectors" )
352352 {
353+ // Check of division expression with unsigned operands
353354 const auto constructed_term =
354355 convert_expr_to_smt (div_exprt{one_bvint_unsigned, two_bvint_unsigned});
355356 const auto expected_term =
356357 smt_bit_vector_theoryt::unsigned_divide (smt_term_one, smt_term_two);
357358 CHECK (constructed_term == expected_term);
359+
360+ // Check of division expression with signed operands
361+ const auto constructed_term_signed =
362+ convert_expr_to_smt (div_exprt{one_bvint, two_bvint});
363+ const auto expected_term_signed =
364+ smt_bit_vector_theoryt::signed_divide (smt_term_one, smt_term_two);
365+ CHECK (constructed_term_signed == expected_term_signed);
358366 }
359367
360368 SECTION (
Original file line number Diff line number Diff line change @@ -252,4 +252,23 @@ TEST_CASE(
252252 // A division of a bool and a bitvector should hit an invariant violation.
253253 REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_divide (true_val, three));
254254 }
255+
256+ SECTION (" Signed Division" )
257+ {
258+ const auto function_application =
259+ smt_bit_vector_theoryt::signed_divide (two, three);
260+ REQUIRE (
261+ function_application.function_identifier () ==
262+ smt_identifier_termt (" bvsdiv" , smt_bit_vector_sortt{8 }));
263+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
264+ REQUIRE (function_application.arguments ().size () == 2 );
265+ REQUIRE (function_application.arguments ()[0 ].get () == two);
266+ REQUIRE (function_application.arguments ()[1 ].get () == three);
267+
268+ cbmc_invariants_should_throwt invariants_throw;
269+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
270+ REQUIRE_THROWS (smt_bit_vector_theoryt::signed_divide (three, four));
271+ // A division of a bool and a bitvector should hit an invariant violation.
272+ REQUIRE_THROWS (smt_bit_vector_theoryt::signed_divide (true_val, three));
273+ }
255274}
You can’t perform that action at this time.
0 commit comments