Skip to content

Commit a8f307b

Browse files
author
Daniel Kroening
committed
fix adjust_float_expressions
adjust_float_expressions adds a rounding mode to floating-point operations when needed. The fix does the following: 1) casts from/to c_bit_field DO need a rounding mode 2) casts from c_bool and bool DO NOT need a rounding mode
1 parent 626e363 commit a8f307b

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

regression/cbmc/Float-no-simp1/main.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1+
#include <assert.h>
2+
3+
struct S
4+
{
5+
unsigned int some_bit : 7;
6+
};
7+
18
int main()
29
{
310
unsigned int i, j;
411
double d;
512

13+
// double to integer and back
614
i=100.0;
715
d=i;
816
j=d;
917
assert(j==100);
18+
19+
// double to bool and back
20+
_Bool b;
21+
b = 100.0;
22+
d = b;
23+
assert(d);
24+
25+
// double to bit-field and back
26+
struct S s;
27+
s.some_bit = 100.0;
28+
d = s.some_bit;
29+
s.some_bit = d;
30+
assert(s.some_bit == 100);
1031
}

src/goto-programs/adjust_float_expressions.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,15 @@ static bool have_to_adjust_float_expressions(const exprt &expr)
5353
if(dest_type.id()==ID_floatbv &&
5454
src_type.id()==ID_floatbv)
5555
return true;
56-
else if(dest_type.id()==ID_floatbv &&
57-
(src_type.id()==ID_c_bool ||
58-
src_type.id()==ID_signedbv ||
59-
src_type.id()==ID_unsignedbv ||
60-
src_type.id()==ID_c_enum_tag))
56+
else if(
57+
dest_type.id() == ID_floatbv &&
58+
(src_type.id() == ID_c_bit_field || src_type.id() == ID_signedbv ||
59+
src_type.id() == ID_unsignedbv || src_type.id() == ID_c_enum_tag))
6160
return true;
62-
else if((dest_type.id()==ID_signedbv ||
63-
dest_type.id()==ID_unsignedbv ||
64-
dest_type.id()==ID_c_enum_tag) &&
65-
src_type.id()==ID_floatbv)
61+
else if(
62+
(dest_type.id() == ID_signedbv || dest_type.id() == ID_unsignedbv ||
63+
dest_type.id() == ID_c_enum_tag || dest_type.id() == ID_c_bit_field) &&
64+
src_type.id() == ID_floatbv)
6665
return true;
6766
}
6867

@@ -136,21 +135,26 @@ void adjust_float_expressions(exprt &expr, const exprt &rounding_mode)
136135
expr.operands().resize(2);
137136
expr.op1()=rounding_mode;
138137
}
139-
else if(dest_type.id()==ID_floatbv &&
140-
(src_type.id()==ID_c_bool ||
141-
src_type.id()==ID_signedbv ||
142-
src_type.id()==ID_unsignedbv ||
143-
src_type.id()==ID_c_enum_tag))
138+
else if(
139+
dest_type.id() == ID_floatbv &&
140+
(src_type.id() == ID_signedbv || src_type.id() == ID_unsignedbv ||
141+
src_type.id() == ID_c_enum_tag || src_type.id() == ID_c_bit_field))
144142
{
145143
// casts from integer to float-type might round
146144
expr.id(ID_floatbv_typecast);
147145
expr.operands().resize(2);
148146
expr.op1()=rounding_mode;
149147
}
150-
else if((dest_type.id()==ID_signedbv ||
151-
dest_type.id()==ID_unsignedbv ||
152-
dest_type.id()==ID_c_enum_tag) &&
153-
src_type.id()==ID_floatbv)
148+
else if(
149+
dest_type.id() == ID_floatbv &&
150+
(src_type.id() == ID_c_bool || src_type.id() == ID_bool))
151+
{
152+
// casts from bool or c_bool to float-type do not need rounding
153+
}
154+
else if(
155+
(dest_type.id() == ID_signedbv || dest_type.id() == ID_unsignedbv ||
156+
dest_type.id() == ID_c_enum_tag || dest_type.id() == ID_c_bit_field) &&
157+
src_type.id() == ID_floatbv)
154158
{
155159
// In C, casts from float to integer always round to zero,
156160
// irrespectively of the rounding mode that is currently set.

0 commit comments

Comments
 (0)