Hi all. A few months ago I did a code sweep to deal with -Wsign-compare warnings generated by gcc. This highlighted issues with how we correctly deal with integer overflow in certain situations, including the interaction between off_t (int64_t) and size_t (uint32_t on ILP32, uint64_t on LP64). A noted example is using the off_t st_size from stat(2) with the size_t len argument to mmap(2), and avoiding overflow on LP64 platforms. Christos & I have been discussing improving the way that we detect and handle these integer overlow issues. I found Felix von Leitner's page: http://www.fefe.de/intof.html which has a good explanation of the issue, as well as some suggestions on dealing with the problem. I've implemented a header file containing some of the macros -- tentatively called <sys/integer_overflow.h> -- which I've attached. I think we could use something like this in our tree. Questions: 1. Does this seem useful to others, in that it could reduce the potential for error ? 2. Is this implementation acceptable? 3. Anyone got a better name than sys/integer_overflow.h ? thanks, Luke.
/* * These macros are from: * http://www.fefe.de/intof.html * Reproduced with permission from Felix von Leitner <felix%fefe.de@localhost>. */ #define __HALF_MAX_SIGNED(type) ((type)1 << (sizeof(type)*8-2)) #define __MAX_SIGNED(type) (__HALF_MAX_SIGNED(type) - 1 + __HALF_MAX_SIGNED(type)) #define __MIN_SIGNED(type) (-1 - __MAX_SIGNED(type)) #define __MIN(type) ((type)-1 < 1?__MIN_SIGNED(type):(type)0) #define __MAX(type) ((type)~__MIN(type)) /* * assigns dest = src * returns non-zero if overflow */ #define assign(dest,src) ({ \ typeof(src) __x=(src); \ typeof(dest) __y=__x; \ (__x==__y && ((__x<1) == (__y<1))?(void)((dest)=__y),0:1); \ }) /* * assigns c = a + b * returns non-zero if overflow occurred */ #define add_overflow(c,a,b) ({ \ typeof(a) __a=a; \ typeof(b) __b=b; \ (__b)<1 ? \ ((__MIN(typeof(c))-(__b)<=(__a))?assign(c,__a+__b):1) : \ ((__MAX(typeof(c))-(__b)>=(__a))?assign(c,__a+__b):1); \ }) /* * assigns c = a - b * returns non-zero if underflow occurred */ #define sub_overflow(c,a,b) ({ \ typeof(a) __a=a; \ typeof(b) __b=b; \ (__b)<1 ? \ ((__MAX(typeof(c))+(__b)>=(__a))?assign(c,__a-__b):1) : \ ((__MIN(typeof(c))+(__b)<=(__a))?assign(c,__a-__b):1); \ })
Attachment:
pgpmXyGpM6y3G.pgp
Description: PGP signature