Skip to content

Commit 4839902

Browse files
authored
Merge pull request #9297 from tautschnig/kiro/rr-41-smt2-arith-crashes
SMT2: support _Bool/enum to fixedbv and fixedbv without fraction
2 parents 4e5fc9b + f344534 commit 4839902

3 files changed

Lines changed: 56 additions & 7 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
typedef __CPROVER_fixedbv[32][16] fix32;
2+
typedef __CPROVER_fixedbv[16][0] fix16_nofrac;
3+
4+
_Bool nondet_bool(void);
5+
enum E
6+
{
7+
A = -1,
8+
B = 1
9+
};
10+
enum E nondet_enum(void);
11+
fix16_nofrac nondet_fix16(void);
12+
13+
int main(void)
14+
{
15+
// c_bool -> fixedbv
16+
_Bool b = nondet_bool();
17+
fix32 d1 = b;
18+
__CPROVER_assert(d1 == 0 || d1 == 1, "c_bool_to_fixedbv");
19+
20+
// c_enum -> fixedbv
21+
enum E e = nondet_enum();
22+
__CPROVER_assume(e == A || e == B);
23+
fix32 d2 = e;
24+
__CPROVER_assert(d2 == -1 || d2 == 1, "enum_to_fixedbv");
25+
26+
// fixedbv with 0 fraction bits -> int
27+
fix16_nofrac d3 = nondet_fix16();
28+
__CPROVER_assume(d3 < 5 && d3 > 2);
29+
int i = d3;
30+
__CPROVER_assert(i == 3 || i == 4, "fixedbv_no_fraction");
31+
32+
return 0;
33+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE no-new-smt
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
9+
--
10+
Typecasts from _Bool and enum types to fixedbv, and from fixedbv types
11+
without fraction bits to integers, must be supported by the SMT2 back end.

‎src/solvers/smt2/smt2_conv.cpp‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3139,8 +3139,13 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
31393139
out << " (ite (and ";
31403140

31413141
// some fraction bit is not zero
3142-
out << "(not (= ((_ extract " << (from_fraction_bits-1) << " 0) ?tcop) "
3143-
"(_ bv0 " << from_fraction_bits << ")))";
3142+
if(from_fraction_bits == 0)
3143+
out << "false";
3144+
else
3145+
{
3146+
out << "(not (= ((_ extract " << (from_fraction_bits - 1)
3147+
<< " 0) ?tcop) (_ bv0 " << from_fraction_bits << ")))";
3148+
}
31443149

31453150
// number negative
31463151
out << " (= ((_ extract " << (from_width-1) << " " << (from_width-1)
@@ -3292,13 +3297,13 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
32923297
std::size_t to_fraction_bits=fixedbv_type.get_fraction_bits();
32933298
std::size_t to_integer_bits=fixedbv_type.get_integer_bits();
32943299

3295-
if(src_type.id()==ID_unsignedbv ||
3296-
src_type.id()==ID_signedbv ||
3297-
src_type.id()==ID_c_enum)
3300+
if(
3301+
src_type.id() == ID_unsignedbv || src_type.id() == ID_signedbv ||
3302+
src_type.id() == ID_c_enum || src_type.id() == ID_c_bool)
32983303
{
32993304
// integer to fixedbv
33003305

3301-
std::size_t from_width=to_bitvector_type(src_type).get_width();
3306+
std::size_t from_width = boolbv_width(src_type);
33023307
out << "(concat ";
33033308

33043309
if(from_width==to_integer_bits)
@@ -3318,7 +3323,7 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
33183323
"from_width should be smaller than to_integer_bits as other case "
33193324
"have been handled above");
33203325
if(
3321-
src_type.id() == ID_unsignedbv ||
3326+
src_type.id() == ID_unsignedbv || src_type.id() == ID_c_bool ||
33223327
(src_type.id() == ID_c_enum &&
33233328
to_c_enum_type(src_type).underlying_type().id() == ID_unsignedbv))
33243329
{

0 commit comments

Comments
 (0)