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 @@ -366,10 +366,22 @@ static smt_termt convert_expr_to_smt(const div_exprt ÷)
366
366
can_cast_type<integer_bitvector_typet>(divide.lhs ().type ()) &&
367
367
can_cast_type<integer_bitvector_typet>(divide.rhs ().type ());
368
368
369
+ const bool both_operands_unsigned =
370
+ can_cast_type<unsignedbv_typet>(divide.lhs ().type ()) &&
371
+ can_cast_type<unsignedbv_typet>(divide.rhs ().type ());
372
+
369
373
if (both_operands_bitvector)
370
374
{
371
- return smt_bit_vector_theoryt::unsigned_divide (
372
- convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
375
+ if (both_operands_unsigned)
376
+ {
377
+ return smt_bit_vector_theoryt::unsigned_divide (
378
+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
379
+ }
380
+ else
381
+ {
382
+ return smt_bit_vector_theoryt::signed_divide (
383
+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
384
+ }
373
385
}
374
386
else
375
387
{
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 @@ -250,4 +250,23 @@ TEST_CASE(
250
250
// A division of a bool and a bitvector should hit an invariant violation.
251
251
REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_divide (true_val, three));
252
252
}
253
+
254
+ SECTION (" Signed Division" )
255
+ {
256
+ const auto function_application =
257
+ smt_bit_vector_theoryt::signed_divide (two, three);
258
+ REQUIRE (
259
+ function_application.function_identifier () ==
260
+ smt_identifier_termt (" bvsdiv" , smt_bit_vector_sortt{8 }));
261
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
262
+ REQUIRE (function_application.arguments ().size () == 2 );
263
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
264
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
265
+
266
+ cbmc_invariants_should_throwt invariants_throw;
267
+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
268
+ REQUIRE_THROWS (smt_bit_vector_theoryt::signed_divide (three, four));
269
+ // A division of a bool and a bitvector should hit an invariant violation.
270
+ REQUIRE_THROWS (smt_bit_vector_theoryt::signed_divide (true_val, three));
271
+ }
253
272
}
You can’t perform that action at this time.
0 commit comments