Skip to content

Commit 69834c1

Browse files
committed
Fix distance check in overflow checking of left shift
The code wrongly compared the shift operand when checking against negative shifts.
1 parent 0ae6010 commit 69834c1

File tree

4 files changed

+14
-4
lines changed

4 files changed

+14
-4
lines changed

regression/cbmc/Overflow_Leftshift1/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <inttypes.h>
2+
13
int main()
24
{
35
unsigned char x;
@@ -23,5 +25,9 @@ int main()
2325
// not an overflow in ANSI-C, but undefined in C99
2426
s = 1 << (sizeof(int) * 8 - 1);
2527

28+
// overflow in an expression where operand and distance types are different
29+
uint32_t u32;
30+
int64_t i64 = (int64_t)upper << 32;
31+
2632
return 0;
2733
}

regression/cbmc/Overflow_Leftshift1/test-c89.desc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ main.c
77
^\[.*\] line 9 arithmetic overflow on signed shl in .*: SUCCESS$
88
^\[.*\] line 15 arithmetic overflow on signed shl in .*: SUCCESS$
99
^\[.*\] line 18 arithmetic overflow on signed shl in .*: FAILURE$
10-
^\*\* 2 of 5 failed
10+
^\[.*\] line 30 arithmetic overflow on signed shl in .*: FAILURE$
11+
^\*\* 3 of 6 failed
1112
^VERIFICATION FAILED$
1213
--
1314
^warning: ignoring

regression/cbmc/Overflow_Leftshift1/test-c99.desc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ main.c
88
^\[.*\] line 15 arithmetic overflow on signed shl in .*: SUCCESS$
99
^\[.*\] line 18 arithmetic overflow on signed shl in .*: FAILURE$
1010
^\[.*\] line 24 arithmetic overflow on signed shl in .*: FAILURE$
11-
^\*\* 3 of 6 failed
11+
^\[.*\] line 30 arithmetic overflow on signed shl in .*: FAILURE$
12+
^\*\* 4 of 7 failed
1213
^VERIFICATION FAILED$
1314
--
1415
^warning: ignoring

src/analyses/goto_check.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -777,8 +777,10 @@ void goto_checkt::integer_overflow_check(
777777
if(distance_type.id() == ID_unsignedbv)
778778
neg_dist_shift = false_exprt();
779779
else
780-
neg_dist_shift =
781-
binary_relation_exprt(op, ID_lt, from_integer(0, distance_type));
780+
{
781+
neg_dist_shift = binary_relation_exprt(
782+
distance, ID_lt, from_integer(0, distance_type));
783+
}
782784

783785
// shifting a non-zero value by more than its width is undefined;
784786
// yet this isn't an overflow

0 commit comments

Comments
 (0)