Skip to content

Commit d33d348

Browse files
Add support for gccs __builtin_sub_overflow primitives
Note: Not the generic version
1 parent 13c9a17 commit d33d348

File tree

3 files changed

+180
-0
lines changed

3 files changed

+180
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include <assert.h>
2+
#include <limits.h>
3+
4+
void check_int(void)
5+
{
6+
int result;
7+
assert(!__builtin_ssub_overflow(1, 1, &result));
8+
assert(result == 0);
9+
assert(__builtin_ssub_overflow(INT_MIN, 1, &result));
10+
assert(!__builtin_ssub_overflow(INT_MIN / 2, INT_MAX / 2, &result));
11+
assert(result - 1 == INT_MIN);
12+
assert(0 && "reachability");
13+
}
14+
15+
void check_long(void)
16+
{
17+
long result;
18+
assert(!__builtin_ssubl_overflow(1l, 1l, &result));
19+
assert(result == 0l);
20+
assert(__builtin_ssubl_overflow(LONG_MIN, 1l, &result));
21+
assert(!__builtin_ssubl_overflow(LONG_MIN / 2l, LONG_MAX / 2l, &result));
22+
assert(result - 1l == LONG_MIN);
23+
assert(0 && "reachability");
24+
}
25+
26+
void check_long_long(void)
27+
{
28+
long result;
29+
assert(!__builtin_ssubl_overflow(1ll, 1ll, &result));
30+
assert(result == 0ll);
31+
assert(__builtin_ssubl_overflow(LLONG_MIN, 1ll, &result));
32+
assert(!__builtin_ssubl_overflow(LLONG_MIN / 2ll, LLONG_MAX / 2ll, &result));
33+
assert(result - 1ll == LLONG_MIN);
34+
assert(0 && "reachability");
35+
}
36+
37+
void check_unsigned(void)
38+
{
39+
unsigned result;
40+
assert(!__builtin_usub_overflow(1u, 1u, &result));
41+
assert(result == 0u);
42+
assert(__builtin_usub_overflow(0u, 1u, &result));
43+
assert(!__builtin_usub_overflow(UINT_MAX / 2u, UINT_MAX / 2u, &result));
44+
assert(result == 0u);
45+
assert(__builtin_usub_overflow(UINT_MAX / 2u, UINT_MAX, &result));
46+
assert(0 && "reachability");
47+
}
48+
49+
void check_unsigned_long(void)
50+
{
51+
unsigned long result;
52+
assert(!__builtin_usubl_overflow(1ul, 1ul, &result));
53+
assert(result == 0ul);
54+
assert(__builtin_usubl_overflow(0ul, 1ul, &result));
55+
assert(!__builtin_usubl_overflow(ULONG_MAX / 2ul, ULONG_MAX / 2ul, &result));
56+
assert(result == 0ul);
57+
assert(__builtin_usubl_overflow(ULONG_MAX / 2ul, ULONG_MAX, &result));
58+
assert(0 && "reachability");
59+
}
60+
61+
void check_unsigned_long_long(void)
62+
{
63+
unsigned long long result;
64+
assert(!__builtin_usubll_overflow(1ull, 1ull, &result));
65+
assert(result == 0ull);
66+
assert(__builtin_usubll_overflow(0ull, 1ull, &result));
67+
assert(
68+
!__builtin_usubll_overflow(ULLONG_MAX / 2ull, ULLONG_MAX / 2ull, &result));
69+
assert(result == 0ull);
70+
assert(__builtin_usubll_overflow(ULLONG_MAX / 2ull, ULLONG_MAX, &result));
71+
assert(0 && "reachability");
72+
}
73+
74+
int main(void)
75+
{
76+
check_int();
77+
check_long();
78+
check_long_long();
79+
check_unsigned();
80+
check_unsigned_long();
81+
check_unsigned_long_long();
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
CORE gcc-only
2+
main.c
3+
4+
\[check_int.assertion.1\] line \d+ assertion !__builtin_ssub_overflow\(1, 1, &result\): SUCCESS
5+
\[check_int.assertion.2\] line \d+ assertion result == 0: SUCCESS
6+
\[check_int.assertion.3\] line \d+ assertion __builtin_ssub_overflow\(.*, 1, &result\): SUCCESS
7+
\[check_int.assertion.4\] line \d+ assertion !__builtin_ssub_overflow\(.* / 2, .* / 2, &result\): SUCCESS
8+
\[check_int.assertion.5\] line \d+ assertion result - 1 == .*: SUCCESS
9+
\[check_int.assertion.6\] line \d+ assertion 0 && "reachability": FAILURE
10+
\[check_long.assertion.1\] line \d+ assertion !__builtin_ssubl_overflow\(1l, 1l, &result\): SUCCESS
11+
\[check_long.assertion.2\] line \d+ assertion result == 0l: SUCCESS
12+
\[check_long.assertion.3\] line \d+ assertion __builtin_ssubl_overflow\(.*, 1l, &result\): SUCCESS
13+
\[check_long.assertion.4\] line \d+ assertion !__builtin_ssubl_overflow\(.* / 2l, .* / 2l, &result\): SUCCESS
14+
\[check_long.assertion.5\] line \d+ assertion result - 1l == .*: SUCCESS
15+
\[check_long.assertion.6\] line \d+ assertion 0 && "reachability": FAILURE
16+
\[check_long_long.assertion.1\] line \d+ assertion !__builtin_ssubl_overflow\(1ll, 1ll, &result\): SUCCESS
17+
\[check_long_long.assertion.2\] line \d+ assertion result == 0ll: SUCCESS
18+
\[check_long_long.assertion.3\] line \d+ assertion __builtin_ssubl_overflow\(.*, 1ll, &result\): SUCCESS
19+
\[check_long_long.assertion.4\] line \d+ assertion !__builtin_ssubl_overflow\(.* / 2ll, .* / 2ll, &result\): SUCCESS
20+
\[check_long_long.assertion.5\] line \d+ assertion result - 1ll == .*: SUCCESS
21+
\[check_long_long.assertion.6\] line \d+ assertion 0 && "reachability": FAILURE
22+
\[check_unsigned.assertion.1\] line \d+ assertion !__builtin_usub_overflow\(1u, 1u, &result\): SUCCESS
23+
\[check_unsigned.assertion.2\] line \d+ assertion result == 0u: SUCCESS
24+
\[check_unsigned.assertion.3\] line \d+ assertion __builtin_usub_overflow\(0u, 1u, &result\): SUCCESS
25+
\[check_unsigned.assertion.4\] line \d+ assertion !__builtin_usub_overflow\(.* / 2u, .* / 2u, &result\): SUCCESS
26+
\[check_unsigned.assertion.5\] line \d+ assertion result == 0u: SUCCESS
27+
\[check_unsigned.assertion.6\] line \d+ assertion __builtin_usub_overflow\(.* / 2u, .*, &result\): SUCCESS
28+
\[check_unsigned.assertion.7\] line \d+ assertion 0 && "reachability": FAILURE
29+
\[check_unsigned_long.assertion.1\] line \d+ assertion !__builtin_usubl_overflow\(1ul, 1ul, &result\): SUCCESS
30+
\[check_unsigned_long.assertion.2\] line \d+ assertion result == 0ul: SUCCESS
31+
\[check_unsigned_long.assertion.3\] line \d+ assertion __builtin_usubl_overflow\(0ul, 1ul, &result\): SUCCESS
32+
\[check_unsigned_long.assertion.4\] line \d+ assertion !__builtin_usubl_overflow\(.* / 2ul, .* / 2ul, &result\): SUCCESS
33+
\[check_unsigned_long.assertion.5\] line \d+ assertion result == 0ul: SUCCESS
34+
\[check_unsigned_long.assertion.6\] line \d+ assertion __builtin_usubl_overflow\(.* / 2ul, .*, &result\): SUCCESS
35+
\[check_unsigned_long.assertion.7\] line \d+ assertion 0 && "reachability": FAILURE
36+
\[check_unsigned_long_long.assertion.1\] line \d+ assertion !__builtin_usubll_overflow\(1ull, 1ull, &result\): SUCCESS
37+
\[check_unsigned_long_long.assertion.2\] line \d+ assertion result == 0ull: SUCCESS
38+
\[check_unsigned_long_long.assertion.3\] line \d+ assertion __builtin_usubll_overflow\(0ull, 1ull, &result\): SUCCESS
39+
\[check_unsigned_long_long.assertion.4\] line \d+ assertion !__builtin_usubll_overflow\(.* / 2ull, .* / 2ull, &result\): SUCCESS
40+
\[check_unsigned_long_long.assertion.5\] line \d+ assertion result == 0ull: SUCCESS
41+
\[check_unsigned_long_long.assertion.6\] line \d+ assertion __builtin_usubll_overflow\(.* / 2ull, .*, &result\): SUCCESS
42+
\[check_unsigned_long_long.assertion.7\] line \d+ assertion 0 && "reachability": FAILURE
43+
^EXIT=10$
44+
^SIGNAL=0$

src/ansi-c/library/math.c

+54
Original file line numberDiff line numberDiff line change
@@ -2352,3 +2352,57 @@ _Bool __builtin_uaddll_overflow(
23522352
*res = a + b;
23532353
return __CPROVER_overflow_plus(a, b);
23542354
}
2355+
2356+
/* FUNCTION: __builtin_ssub_overflow */
2357+
2358+
_Bool __builtin_ssub_overflow(int a, int b, int *res)
2359+
{
2360+
*res = a - b;
2361+
return __CPROVER_overflow_minus(a, b);
2362+
}
2363+
2364+
/* FUNCTION: __builtin_ssubl_overflow */
2365+
2366+
_Bool __builtin_ssubl_overflow(long a, long b, long *res)
2367+
{
2368+
*res = a - b;
2369+
return __CPROVER_overflow_minus(a, b);
2370+
}
2371+
2372+
/* FUNCTION: __builtin_ssubll_overflow */
2373+
2374+
_Bool __builtin_ssubll_overflow(long long a, long long b, long long *res)
2375+
{
2376+
*res = a - b;
2377+
return __CPROVER_overflow_minus(a, b);
2378+
}
2379+
2380+
/* FUNCTION: __builtin_usub_overflow */
2381+
2382+
_Bool __builtin_usub_overflow(unsigned a, unsigned b, unsigned *res)
2383+
{
2384+
*res = a - b;
2385+
return __CPROVER_overflow_minus(a, b);
2386+
}
2387+
2388+
/* FUNCTION: __builtin_usubl_overflow */
2389+
2390+
_Bool __builtin_usubl_overflow(
2391+
unsigned long a,
2392+
unsigned long b,
2393+
unsigned long *res)
2394+
{
2395+
*res = a - b;
2396+
return __CPROVER_overflow_minus(a, b);
2397+
}
2398+
2399+
/* FUNCTION: __builtin_usubll_overflow */
2400+
2401+
_Bool __builtin_usubll_overflow(
2402+
unsigned long long a,
2403+
unsigned long long b,
2404+
unsigned long long *res)
2405+
{
2406+
*res = a - b;
2407+
return __CPROVER_overflow_minus(a, b);
2408+
}

0 commit comments

Comments
 (0)