Skip to content

Commit cc990f5

Browse files
authored
Merge pull request #6324 from diffblue/overflow_unsigned_unary_minus
Check overflow on unsigned unary minus
2 parents 942685c + 448421b commit cc990f5

19 files changed

+85
-33
lines changed

regression/cbmc/Overflow_Multiplication1/falsealarm.c

Lines changed: 0 additions & 13 deletions
This file was deleted.

regression/cbmc/Overflow_Leftshift1/test-c89.desc renamed to regression/cbmc/overflow/leftshift_overflow-c89.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE
2-
main.c
2+
leftshift_overflow.c
33
--signed-overflow-check --c89
44
^EXIT=10$
55
^SIGNAL=0$

regression/cbmc/Overflow_Leftshift1/test-c99.desc renamed to regression/cbmc/overflow/leftshift_overflow-c99.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE
2-
main.c
2+
leftshift_overflow.c
33
--signed-overflow-check --c99
44
^EXIT=10$
55
^SIGNAL=0$

regression/cbmc/Overflow_Leftshift1/main.c renamed to regression/cbmc/overflow/leftshift_overflow.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ int main()
88
unsigned r = x << ((sizeof(unsigned) - 1) * 8 + 1);
99

1010
// signed, owing to promotion, and cannot overflow
11-
r=x << ((sizeof(unsigned)-1)*8-1);
11+
r = x << ((sizeof(unsigned) - 1) * 8 - 1);
1212

1313
// unsigned
14-
r=(unsigned)x << ((sizeof(unsigned)-1)*8);
14+
r = (unsigned)x << ((sizeof(unsigned) - 1) * 8);
1515

1616
// negative value or zero, not an overflow
1717
int s = -x << ((sizeof(int) - 1) * 8);
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
int main() {
1+
int main()
2+
{
23
signed int i, j;
34

4-
i=j;
5+
i = j;
56

67
i++;
78
}

regression/cbmc/Overflow_Addition1/test.desc renamed to regression/cbmc/overflow/signed_addition_overflow1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE
2-
main.c
2+
signed_addition_overflow1.c
33
--signed-overflow-check
44
^EXIT=10$
55
^SIGNAL=0$

regression/cbmc/Overflow_Addition2/test.desc renamed to regression/cbmc/overflow/signed_addition_overflow2.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE
2-
main.c
2+
signed_addition_overflow2.c
33
--signed-overflow-check
44
^EXIT=10$
55
^SIGNAL=0$

regression/cbmc/Overflow_Addition3/test.desc renamed to regression/cbmc/overflow/signed_addition_overflow3.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE
2-
main.c
2+
signed_addition_overflow3.c
33
--signed-overflow-check --conversion-check
44
^EXIT=10$
55
^SIGNAL=0$

regression/cbmc/Overflow_Addition4/test.desc renamed to regression/cbmc/overflow/signed_addition_overflow4.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE
2-
main.c
2+
signed_addition_overflow4.c
33
--signed-overflow-check --conversion-check
44
^EXIT=10$
55
^SIGNAL=0$
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// From Cousot's FMSD paper
2+
3+
void main()
4+
{
5+
int x, y, _x, _y;
6+
7+
x = _x;
8+
y = _y;
9+
10+
if(
11+
(-4681 < y) && (y < 4681) && (x < 32767) && (-32767 < x) &&
12+
((7 * y * y - 1) == x * x))
13+
{
14+
y = 1 / x;
15+
}
16+
}

regression/cbmc/Overflow_Subtraction1/test.desc renamed to regression/cbmc/overflow/signed_multiplication1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE
2-
main.c
2+
signed_multiplication1.c
33
--signed-overflow-check
44
^EXIT=0$
55
^SIGNAL=0$
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
#define INT_MIN (-1<<(sizeof(int)*8-1))
1+
#define INT_MIN (-1 << (sizeof(int) * 8 - 1))
22

33
int main()
44
{
55
int a, b, neg;
66

77
// this should not overflow, even not for a=INT_MIN
8-
b=a-a;
8+
b = a - a;
99

1010
// this should also not overflow as long as pos<0
11-
if(neg<0)
12-
b=neg-INT_MIN;
11+
if(neg < 0)
12+
b = neg - INT_MIN;
1313

1414
int x, y, z;
1515

16-
x = INT_MIN+1;
16+
x = INT_MIN + 1;
1717
y = INT_MIN;
18-
z = x-y; // neither
18+
z = x - y; // neither
1919
}

regression/cbmc/Overflow_Multiplication1/test.desc renamed to regression/cbmc/overflow/signed_subtraction1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE
2-
falsealarm.c
2+
signed_subtraction1.c
33
--signed-overflow-check
44
^EXIT=0$
55
^SIGNAL=0$
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <limits.h>
2+
3+
int main()
4+
{
5+
signed int x, y;
6+
7+
x = INT_MIN;
8+
9+
// this is an overflow
10+
y = -x;
11+
12+
// ok
13+
x = -(x + 1);
14+
15+
unsigned a, b;
16+
17+
a = 1;
18+
a = -a; // overflow, -1 is not representable
19+
20+
b = 0;
21+
b = -b; // ok
22+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
unary_minus_overflow.c
3+
--signed-overflow-check --unsigned-overflow-check
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[.*\] line .* arithmetic overflow on signed unary minus in -x: FAILURE$
7+
^\[.*\] line .* arithmetic overflow on signed unary minus in -\(x \+ 1\): SUCCESS$
8+
^\[.*\] line .* arithmetic overflow on unsigned unary minus in -a: SUCCESS$
9+
^\[.*\] line .* arithmetic overflow on unsigned unary minus in -b: FAILURE$
10+
--

src/analyses/goto_check.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,8 +734,8 @@ void goto_checkt::integer_overflow_check(
734734
{
735735
if(type.id()==ID_signedbv)
736736
{
737-
// overflow on unary- can only happen with the smallest
738-
// representable number 100....0
737+
// overflow on unary- on signed integers can only happen with the
738+
// smallest representable number 100....0
739739

740740
equal_exprt int_min_eq(
741741
to_unary_minus_expr(expr).op(), to_signedbv_type(type).smallest_expr());
@@ -748,6 +748,22 @@ void goto_checkt::integer_overflow_check(
748748
expr,
749749
guard);
750750
}
751+
else if(type.id() == ID_unsignedbv)
752+
{
753+
// Overflow on unary- on unsigned integers happens for all operands
754+
// that are not zero.
755+
756+
notequal_exprt not_eq_zero(
757+
to_unary_minus_expr(expr).op(), to_unsignedbv_type(type).zero_expr());
758+
759+
add_guarded_property(
760+
not_eq_zero,
761+
"arithmetic overflow on unsigned unary minus",
762+
"overflow",
763+
expr.find_source_location(),
764+
expr,
765+
guard);
766+
}
751767

752768
return;
753769
}

0 commit comments

Comments
 (0)