Skip to content

Commit d1dc64f

Browse files
committed
preconditions for abs, labs, llabs, imaxabs
C99 states that the behavior of abs, labs, llabs, imaxabs is undefined when the result of computing the absolute value is not representable. This commit adds preconditions to the library models that catch this case.
1 parent 63b8b71 commit d1dc64f

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

regression/cbmc-library/abs-01/main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <limits.h>
12
#include <math.h>
23
#include <stdlib.h>
34

@@ -17,7 +18,8 @@ int main()
1718
assert(fabs(-1.0) == 1);
1819

1920
iabs = (my_i < 0) ? -my_i : my_i;
20-
assert(abs(my_i) == iabs);
21+
if(my_i != INT_MIN)
22+
assert(abs(my_i) == iabs);
2123

2224
__CPROVER_assume(!isnan(my_d));
2325

src/ansi-c/library/stdlib.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,53 @@
11
/* FUNCTION: abs */
22

3+
#ifndef __CPROVER_LIMITS_H_INCLUDED
4+
# include <limits.h>
5+
# define __CPROVER_LIMITS_H_INCLUDED
6+
#endif
7+
38
#undef abs
49

510
int abs(int i)
611
{
12+
// C99 Section 7.20.6.1:
13+
// "If the result cannot be represented, the behavior is undefined."
14+
__CPROVER_precondition(i != INT_MIN, "argument to abs must not be INT_MIN");
715
return __CPROVER_abs(i);
816
}
917

1018
/* FUNCTION: labs */
1119

20+
#ifndef __CPROVER_LIMITS_H_INCLUDED
21+
# include <limits.h>
22+
# define __CPROVER_LIMITS_H_INCLUDED
23+
#endif
24+
1225
#undef labs
1326

1427
long int labs(long int i)
1528
{
29+
// C99 Section 7.20.6.1:
30+
// "If the result cannot be represented, the behavior is undefined."
31+
__CPROVER_precondition(
32+
i != LONG_MIN, "argument to labs must not be LONG_MIN");
1633
return __CPROVER_labs(i);
1734
}
1835

1936
/* FUNCTION: llabs */
2037

38+
#ifndef __CPROVER_LIMITS_H_INCLUDED
39+
# include <limits.h>
40+
# define __CPROVER_LIMITS_H_INCLUDED
41+
#endif
42+
2143
#undef llabs
2244

2345
long long int llabs(long long int i)
2446
{
47+
// C99 Section 7.20.6.1:
48+
// "If the result cannot be represented, the behavior is undefined."
49+
__CPROVER_precondition(
50+
i != LLONG_MIN, "argument to llabs must not be LLONG_MIN");
2551
return __CPROVER_llabs(i);
2652
}
2753

@@ -32,12 +58,19 @@ long long int llabs(long long int i)
3258
# define __CPROVER_INTTYPES_H_INCLUDED
3359
#endif
3460

61+
#ifndef __CPROVER_LIMITS_H_INCLUDED
62+
# include <limits.h>
63+
# define __CPROVER_LIMITS_H_INCLUDED
64+
#endif
65+
3566
#undef imaxabs
3667

3768
intmax_t __CPROVER_imaxabs(intmax_t);
3869

3970
intmax_t imaxabs(intmax_t i)
4071
{
72+
__CPROVER_precondition(
73+
i != INTMAX_MIN, "argument to imaxabs must not be INTMAX_MIN");
4174
return __CPROVER_imaxabs(i);
4275
}
4376

0 commit comments

Comments
 (0)