tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Dealing with integer overflow issues



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



Home | Main Index | Thread Index | Old Index