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 ÷)
365
365
can_cast_type<integer_bitvector_typet>(divide.lhs ().type ()) &&
366
366
can_cast_type<integer_bitvector_typet>(divide.rhs ().type ());
367
367
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
+
368
372
if (both_operands_bitvector)
369
373
{
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
+ }
372
384
}
373
385
else
374
386
{
Original file line number Diff line number Diff line change @@ -296,3 +296,26 @@ void smt_bit_vector_theoryt::unsigned_dividet::validate(
296
296
const smt_function_application_termt::factoryt<
297
297
smt_bit_vector_theoryt::unsigned_dividet>
298
298
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
117
117
};
118
118
static const smt_function_application_termt::factoryt<unsigned_dividet>
119
119
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;
120
129
};
121
130
122
131
#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(
350
350
// truncates over zero)
351
351
SECTION (" Division of two constant size bit-vectors" )
352
352
{
353
+ // Check of division expression with unsigned operands
353
354
const auto constructed_term =
354
355
convert_expr_to_smt (div_exprt{one_bvint_unsigned, two_bvint_unsigned});
355
356
const auto expected_term =
356
357
smt_bit_vector_theoryt::unsigned_divide (smt_term_one, smt_term_two);
357
358
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);
358
366
}
359
367
360
368
SECTION (
Original file line number Diff line number Diff line change @@ -252,4 +252,23 @@ TEST_CASE(
252
252
// A division of a bool and a bitvector should hit an invariant violation.
253
253
REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_divide (true_val, three));
254
254
}
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
+ }
255
274
}
You can’t perform that action at this time.
0 commit comments