diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-03-02 15:32:56 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-03-02 15:32:56 +0000 |
commit | a6d06d7b86f724046b462115556d0df682f9f703 (patch) | |
tree | 640870a7d978c8a224fe317e862b65fddba6f40e /sysdeps/ieee754 | |
parent | 07e12bb391ae84eb74817d42feda42cff7f687e5 (diff) | |
download | glibc-a6d06d7b86f724046b462115556d0df682f9f703.zip glibc-a6d06d7b86f724046b462115556d0df682f9f703.tar.gz glibc-a6d06d7b86f724046b462115556d0df682f9f703.tar.bz2 |
Fix scalbn, scalbln integer overflow.
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r-- | sysdeps/ieee754/dbl-64/s_scalbln.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/s_scalbn.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/flt-32/s_scalblnf.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/flt-32/s_scalbnf.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_scalblnl.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_scalbnl.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/s_scalblnl.c | 8 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/s_scalbnl.c | 8 |
12 files changed, 60 insertions, 36 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_scalbln.c b/sysdeps/ieee754/dbl-64/s_scalbln.c index 89174b4..b5903c9 100644 --- a/sysdeps/ieee754/dbl-64/s_scalbln.c +++ b/sysdeps/ieee754/dbl-64/s_scalbln.c @@ -38,11 +38,13 @@ __scalbln (double x, long int n) k = ((hx&0x7ff00000)>>20) - 54; } if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysign(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) + return huge*__copysign(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} if (k <= -54) diff --git a/sysdeps/ieee754/dbl-64/s_scalbn.c b/sysdeps/ieee754/dbl-64/s_scalbn.c index 1e67dbe..c2488fb 100644 --- a/sysdeps/ieee754/dbl-64/s_scalbn.c +++ b/sysdeps/ieee754/dbl-64/s_scalbn.c @@ -38,11 +38,13 @@ __scalbn (double x, int n) k = ((hx&0x7ff00000)>>20) - 54; } if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysign(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) + return huge*__copysign(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} if (k <= -54) diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c index d6b97b5..1d0da68 100644 --- a/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c @@ -39,11 +39,13 @@ __scalbln (double x, long int n) k = ((ix >> 52) & 0x7ff) - 54; } if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysign(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) + return huge*__copysign(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {INSERT_WORDS64(x,(ix&UINT64_C(0x800fffffffffffff))|(k<<52)); return x;} diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c index 7f0e21f..e183c38 100644 --- a/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c @@ -39,11 +39,13 @@ __scalbn (double x, int n) k = ((ix >> 52) & 0x7ff) - 54; } if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysign(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) + return huge*__copysign(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {INSERT_WORDS64(x,(ix&UINT64_C(0x800fffffffffffff))|(k<<52)); return x;} diff --git a/sysdeps/ieee754/flt-32/s_scalblnf.c b/sysdeps/ieee754/flt-32/s_scalblnf.c index 5256c32..2a2d7ab 100644 --- a/sysdeps/ieee754/flt-32/s_scalblnf.c +++ b/sysdeps/ieee754/flt-32/s_scalblnf.c @@ -35,11 +35,13 @@ __scalblnf (float x, long int n) k = ((ix&0x7f800000)>>23) - 25; } if (__builtin_expect(k==0xff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0xfe, 0)) - return huge*copysignf(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*copysignf(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0xfe, 0)) + return huge*copysignf(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} if (k <= -25) diff --git a/sysdeps/ieee754/flt-32/s_scalbnf.c b/sysdeps/ieee754/flt-32/s_scalbnf.c index 3be2925..a7cb1a1 100644 --- a/sysdeps/ieee754/flt-32/s_scalbnf.c +++ b/sysdeps/ieee754/flt-32/s_scalbnf.c @@ -35,11 +35,13 @@ __scalbnf (float x, int n) k = ((ix&0x7f800000)>>23) - 25; } if (__builtin_expect(k==0xff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0xfe, 0)) - return huge*__copysignf(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysignf(tiny,x); /*underflow*/ + if (__builtin_expect(n> 50000 || k+n > 0xfe, 0)) + return huge*__copysignf(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} if (k <= -25) diff --git a/sysdeps/ieee754/ldbl-128/s_scalblnl.c b/sysdeps/ieee754/ldbl-128/s_scalblnl.c index f5624e2..9ad976b 100644 --- a/sysdeps/ieee754/ldbl-128/s_scalblnl.c +++ b/sysdeps/ieee754/ldbl-128/s_scalblnl.c @@ -46,10 +46,12 @@ long double __scalblnl (long double x, long int n) k = ((hx>>48)&0x7fff) - 114; } if (k==0x7fff) return x+x; /* NaN or Inf */ - k = k+n; - if (n> 50000 || k > 0x7ffe) - return huge*__copysignl(huge,x); /* overflow */ if (n< -50000) return tiny*__copysignl(tiny,x); /*underflow*/ + if (n> 50000 || k+n > 0x7ffe) + return huge*__copysignl(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (k > 0) /* normal result */ {SET_LDOUBLE_MSW64(x,(hx&0x8000ffffffffffffULL)|(k<<48)); return x;} if (k <= -114) diff --git a/sysdeps/ieee754/ldbl-128/s_scalbnl.c b/sysdeps/ieee754/ldbl-128/s_scalbnl.c index b9de0f7..a928ecc 100644 --- a/sysdeps/ieee754/ldbl-128/s_scalbnl.c +++ b/sysdeps/ieee754/ldbl-128/s_scalbnl.c @@ -46,10 +46,12 @@ long double __scalbnl (long double x, int n) k = ((hx>>48)&0x7fff) - 114; } if (k==0x7fff) return x+x; /* NaN or Inf */ - k = k+n; - if (n> 50000 || k > 0x7ffe) - return huge*__copysignl(huge,x); /* overflow */ if (n< -50000) return tiny*__copysignl(tiny,x); /*underflow*/ + if (n> 50000 || k+n > 0x7ffe) + return huge*__copysignl(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (k > 0) /* normal result */ {SET_LDOUBLE_MSW64(x,(hx&0x8000ffffffffffffULL)|(k<<48)); return x;} if (k <= -114) diff --git a/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c b/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c index a1632e7..2c30d1c 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c @@ -52,10 +52,12 @@ long double __scalblnl (long double x, long int n) k = ((hx>>52)&0x7ff) - 54; } else if (k==0x7ff) return x+x; /* NaN or Inf */ - k = k+n; - if (n> 50000 || k > 0x7fe) - return huge*__copysignl(huge,x); /* overflow */ if (n< -50000) return tiny*__copysignl(tiny,x); /*underflow */ + if (n> 50000 || k+n > 0x7fe) + return huge*__copysignl(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (k > 0) { /* normal result */ hx = (hx&0x800fffffffffffffULL)|(k<<52); if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c b/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c index a52cd42..48102ef 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c @@ -52,10 +52,12 @@ long double __scalbnl (long double x, int n) k = ((hx>>52)&0x7ff) - 54; } else if (k==0x7ff) return x+x; /* NaN or Inf */ - k = k+n; - if (n> 50000 || k > 0x7fe) - return huge*__copysignl(huge,x); /* overflow */ if (n< -50000) return tiny*__copysignl(tiny,x); /*underflow */ + if (n> 50000 || k+n > 0x7fe) + return huge*__copysignl(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (k > 0) { /* normal result */ hx = (hx&0x800fffffffffffffULL)|(k<<52); if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */ diff --git a/sysdeps/ieee754/ldbl-96/s_scalblnl.c b/sysdeps/ieee754/ldbl-96/s_scalblnl.c index ada587b..755a212 100644 --- a/sysdeps/ieee754/ldbl-96/s_scalblnl.c +++ b/sysdeps/ieee754/ldbl-96/s_scalblnl.c @@ -43,11 +43,13 @@ __scalblnl (long double x, long int n) k = (hx&0x7fff) - 63; } if (__builtin_expect(k==0x7fff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7ffe, 0)) - return huge*__copysignl(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysignl(tiny,x); + if (__builtin_expect(n> 50000 || k+n > 0x7ffe, 0)) + return huge*__copysignl(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {SET_LDOUBLE_EXP(x,(es&0x8000)|k); return x;} if (k <= -63) diff --git a/sysdeps/ieee754/ldbl-96/s_scalbnl.c b/sysdeps/ieee754/ldbl-96/s_scalbnl.c index 6a41920..6946cf2 100644 --- a/sysdeps/ieee754/ldbl-96/s_scalbnl.c +++ b/sysdeps/ieee754/ldbl-96/s_scalbnl.c @@ -43,11 +43,13 @@ __scalbnl (long double x, int n) k = (hx&0x7fff) - 64; } if (__builtin_expect(k==0x7fff, 0)) return x+x; /* NaN or Inf */ - k = k+n; - if (__builtin_expect(n> 50000 || k > 0x7ffe, 0)) - return huge*__copysignl(huge,x); /* overflow */ if (__builtin_expect(n< -50000, 0)) return tiny*__copysignl(tiny,x); + if (__builtin_expect(n> 50000 || k+n > 0x7ffe, 0)) + return huge*__copysignl(huge,x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k+n; if (__builtin_expect(k > 0, 1)) /* normal result */ {SET_LDOUBLE_EXP(x,(es&0x8000)|k); return x;} if (k <= -64) |