Overflow builtins

| Comments

Since it’s non-trivial to do integer overflow checking correctly and efficiently (see my email to cfe-dev and previous post on libo), let’s try compiler support. Just gave it a shot in Clang. My patch is available on the builtin-overflow branch. It introduces bool __overflow_*(T *, T, T) builtin functions, which are easier to understand, less error-prone, and have better performance (e.g., only one more jno instruction on x86 for most cases). Here is an example.

1
2
3
4
5
6
7
void *malloc_array(size_t n, size_t size)
{
	size_t bytes;
	if (__overflow_umul(&bytes, n, size))
		return NULL;
	return malloc(bytes);
}

One more example: signed addition overflow detection mentioned in the previous post. Below is the implementation from CERT’s IntegerLib.

1
2
3
4
5
6
7
8
9
signed long addsl(signed long lhs, signed long rhs)
{
	errno = 0;
	if( (((lhs+rhs)^lhs)&((lhs+rhs)^rhs)) >> (sizeof(int)*CHAR_BIT-1) ) {
		error_handler("OVERFLOW ERROR", NULL, EOVERFLOW);
		errno = EINVAL;
	}
	return lhs+rhs;
}

Anything suspicious? Despite the clever bit trick, the code is undefined because signed overflow can happen before the check. It also doesn’t work on 64-bit platform: sizeof(int) should be sizeof(long). But now you can simply write __overflow_sadd, without worrying about undefined behavior nor performance.

Interested in overflow builtins, found any bugs, or got better ideas about the interface and function names? Leave your comments or join the discussions at bugzilla and cfe-dev.

Comments