Skip to content

Commit 17dbc9f

Browse files
Add support for GCCs __builtin_add_overflow primitives
Note: Not the generic version.
1 parent fa1f359 commit 17dbc9f

File tree

3 files changed

+153
-0
lines changed

3 files changed

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

src/ansi-c/library/math.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,5 +2299,44 @@ long double copysignl(long double x, long double y)
22992299
return (signbit(y)) ? -abs : abs;
23002300
}
23012301

2302+
/* FUNCTION: __builtin_sadd_overflow */
23022303

2304+
_Bool __builtin_sadd_overflow(int a, int b, int *res) {
2305+
*res = a + b;
2306+
return __CPROVER_overflow_plus(a, b);
2307+
}
2308+
2309+
/* FUNCTION: __builtin_saddl_overflow */
2310+
2311+
_Bool __builtin_saddl_overflow(long a, long b, long *res) {
2312+
*res = a + b;
2313+
return __CPROVER_overflow_plus(a, b);
2314+
}
2315+
2316+
/* FUNCTION: __builtin_saddll_overflow */
2317+
2318+
_Bool __builtin_saddll_overflow(long long a, long long b, long long *res) {
2319+
*res = a + b;
2320+
return __CPROVER_overflow_plus(a, b);
2321+
}
2322+
2323+
/* FUNCTION: __builtin_uadd_overflow */
23032324

2325+
_Bool __builtin_uadd_overflow(unsigned a, unsigned b, unsigned *res) {
2326+
*res = a + b;
2327+
return __CPROVER_overflow_plus(a, b);
2328+
}
2329+
2330+
/* FUNCTION: __builtin_uaddl_overflow */
2331+
2332+
_Bool __builtin_uaddl_overflow(unsigned long a, unsigned long b, unsigned long *res) {
2333+
*res = a + b;
2334+
return __CPROVER_overflow_plus(a, b);
2335+
}
2336+
2337+
/* FUNCTION: __builtin_uaddll_overflow */
2338+
2339+
_Bool __builtin_uaddll_overflow(unsigned long long a, unsigned long long b, unsigned long long *res) {
2340+
*res = a + b;
2341+
return __CPROVER_overflow_plus(a, b);
2342+
}

0 commit comments

Comments
 (0)