add gcc 5 integer overflow intrinsics support to rangecheck.h

in the process, identify a gnarly problem that was not only not found by
  the test suite, there was a test testing for the wrong behavior!
master
leitner 9 years ago
parent 7bdc1b29bb
commit 6cfc16fc40

@ -147,11 +147,21 @@ int range_str4inbuf(const void* buf,size_t len,const void* stringstart);
#define assign(dest,src) ({ typeof(src) __x=(src); typeof(dest) __y=__x; (__x==__y && ((__x<1) == (__y<1))?(void)((dest)=__y),0:1); })
/* gcc 5 now has nice builtins we can use instead */
#if defined(__GNUC__) && (__GNUC__ >= 5)
#define add_of(c,a,b) __builtin_add_overflow(a,b,&c)
#define sub_of(c,a,b) __builtin_sub_overflow(a,b,&c)
#else
/* if a+b is defined and does not have an integer overflow, do c=a+b and
* return 0. Otherwise, return 1. */
#define add_of(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); })
#define add_of(c,a,b) ({ typeof(a) __a=a; typeof(b) __b=b; (__b)<1?((__MIN(typeof(a+b))-(__b)<=(__a))?assign(c,__a+__b):1) : ((__MAX(typeof(c))-(__b)>=(__a))?assign(c,__a+__b):1); })
#define sub_of(c,a,b) ({ typeof(a) __a=a; typeof(b) __b=b; (__b)<1?((__MAX(typeof(a+b))+__b>=__a)?assign(c,__a-__b):1) : ((__MIN(typeof(c))+__b<=__a)?assign(c,__a-__b):1); })
#define sub_of(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); })
#endif
#undef __static

@ -177,7 +177,7 @@ void check_intof() {
a=0; assert(add_of(a,UINT_MAX-3,4)==1);
a=0; assert(add_of(a,2,-3)==1);
a=23; assert(add_of(a,2,-2)==0 && a==0);
a=0; assert(add_of(a,(int)0x80000000,(int)-2147483648)==0 && a==0);
a=23; assert(sub_of(a,(int)0x80000000,(int)-2147483648)==0 && a==0);
a=0; assert(add_of(a,(int)0x7fffffff,(int)-2147483648)==1);
a=0; assert(add_of(a,1,UINT_MAX)==1);

Loading…
Cancel
Save