Skip to content

Commit 59a3c2a

Browse files
committed
implicit_typecast_arithmetic must not assume types are bitvectors
We use Booleans instead of int as type of binary predicates, and enums don't convert to bitvector types directly either. This must not preclude mixing binary predicates with bitvector-typed expressions. Fixes: diffblue#5103
1 parent c99dcc8 commit 59a3c2a

File tree

5 files changed

+48
-17
lines changed

5 files changed

+48
-17
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int main(int argc, char *argv[])
2+
{
3+
unsigned __int128 z;
4+
z = (unsigned __int128)argc;
5+
z += (argc < 1);
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE gcc-only
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^CONVERSION ERROR$

regression/cbmc/enum9/main.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <limits.h>
2+
3+
enum E
4+
{
5+
V1 = 1,
6+
V2 = 2
7+
};
8+
9+
struct B
10+
{
11+
unsigned b : 2;
12+
};
13+
14+
int main()
15+
{
16+
unsigned __int128 int x;
17+
__CPROVER_assume(x < (~(unsigned __int128)0) - 4);
18+
19+
enum E e;
20+
__CPROVER_assume(__CPROVER_enum_is_in_range(e));
21+
__CPROVER_assert(x + e > x, "long long plus enum");
22+
23+
struct B b;
24+
__CPROVER_assert(x + b.b >= x, "long long plus bitfield");
25+
}

regression/cbmc/enum9/test.desc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE gcc-only
2+
main.c
3+
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^CONVERSION ERROR$
9+
^warning: ignoring

src/ansi-c/c_typecast.cpp

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -650,24 +650,8 @@ void c_typecastt::implicit_typecast_arithmetic(
650650

651651
if(max_type==LARGE_SIGNED_INT || max_type==LARGE_UNSIGNED_INT)
652652
{
653-
// get the biggest width of both
654-
std::size_t width1 = to_bitvector_type(type1).get_width();
655-
std::size_t width2 = to_bitvector_type(type2).get_width();
656-
657653
// produce type
658-
typet result_type;
659-
660-
if(width1==width2)
661-
{
662-
if(max_type==LARGE_SIGNED_INT)
663-
result_type=signedbv_typet(width1);
664-
else
665-
result_type=unsignedbv_typet(width1);
666-
}
667-
else if(width1>width2)
668-
result_type=type1;
669-
else // width1<width2
670-
result_type=type2;
654+
typet result_type = (max_type == c_type1) ? type1 : type2;
671655

672656
do_typecast(expr1, result_type);
673657
do_typecast(expr2, result_type);

0 commit comments

Comments
 (0)