This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Use <intprops.h> within glibc for integer overflow checks?
- From: Paul Eggert <eggert at cs dot ucla dot edu>
- To: libc-alpha at sourceware dot org
- Cc: Nickolai Zeldovich <nickolai at csail dot mit dot edu>
- Date: Wed, 15 May 2013 14:42:12 -0700
- Subject: Use <intprops.h> within glibc for integer overflow checks?
- References: <1368637095-20325-1-git-send-email-nickolai at csail dot mit dot edu>
On 05/15/13 09:58, Nickolai Zeldovich wrote:
> +#define __HALF_MAX_SIGNED(type) \
> + ((type)1 << (sizeof(type)*8-2))
> +#define __MAX_SIGNED(type) \
> + (__HALF_MAX_SIGNED(type) - 1 + __HALF_MAX_SIGNED(type))
> ...
> - if (offset + len < 0)
> + if (offset > __MAX_SIGNED(__off_t) - len)
At some point perhaps glibc should steal the <intprops.h>
header from gnulib, for internal use. That way, the above
code could be simplified to:
#include <intprops.h>
...
if (INT_ADD_OVERFLOW (offset, len))
without the need for defining __MAX_SIGNED or __HALF_MAX_SIGNED,
as that's all handled internally by intprops.h. This would
make overflow-checking code more readable.
I just now tried this in the sample program at the end of this
message, and GCC generated exactly the same machine code for the
intprops version as it did for the harder-to-read version.
You can get a copy of intprops.h from:
http://git.savannah.gnu.org/cgit/gnulib.git/plain/lib/intprops.h
Here's the sample program:
#include <intprops.h>
int
harder_to_read_version (long long offset, long long len)
{
if (offset < 0 || len < 0)
return 1;
if (offset > LLONG_MAX - len)
return 2;
return 0;
}
int
intprops_version (long long offset, long long len)
{
if (offset < 0 || len < 0)
return 1;
if (INT_ADD_OVERFLOW (offset, len))
return 2;
return 0;
}