Fix scalbn, scalbln integer overflow.

This commit is contained in:
Joseph Myers 2012-03-02 15:32:56 +00:00
parent 07e12bb391
commit a6d06d7b86
15 changed files with 121 additions and 40 deletions

View File

@ -1,5 +1,24 @@
2012-03-02 Joseph Myers <joseph@codesourcery.com>
[BZ #10135]
* sysdeps/ieee754/dbl-64/s_scalbln.c (__scalbln): First test for
small n, then large n, before computing and testing k+n.
* sysdeps/ieee754/dbl-64/s_scalbn.c (__scalbn): Likewise.
* sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c (__scalbln):
Likewise.
* sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c (__scalbn):
Likewise.
* sysdeps/ieee754/flt-32/s_scalblnf.c (__scalblnf): Likewise.
* sysdeps/ieee754/flt-32/s_scalbnf.c (__scalbnf): Likewise.
* sysdeps/ieee754/ldbl-128/s_scalblnl.c (__scalblnl): Likewise.
* sysdeps/ieee754/ldbl-128/s_scalbnl.c (__scalbnl): Likewise.
* sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c (__scalblnl): Likewise.
* sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c (__scalbnl): Likewise.
* sysdeps/ieee754/ldbl-96/s_scalblnl.c (__scalblnl): Likewise.
* sysdeps/ieee754/ldbl-96/s_scalbnl.c (__scalbnl): Likewise.
* math/libm-test.inc (scalbn_test): Add more tests.
(scalbln_test): Likewise.
* manual/filesys.texi (mode_t): Describe constraints on size and
signedness, not exact equivalence to a particular type.
(ino_t): Likewise.

8
NEWS
View File

@ -10,10 +10,10 @@ Version 2.16
* The following bugs are resolved with this release:
174, 350, 411, 2541, 2547, 2548, 3335, 3992, 4026, 4108, 4596, 4822, 5077,
5461, 5805, 5993, 6884, 6907, 9739, 9902, 10110, 10140, 10210, 11174,
11322, 11365, 11494, 12047, 13058, 13525, 13526, 13527, 13528, 13529,
13530, 13531, 13532, 13533, 13547, 13551, 13552, 13553, 13555, 13559,
13583, 13618, 13637, 13695, 13704, 13706, 13738, 13786
5461, 5805, 5993, 6884, 6907, 9739, 9902, 10110, 10135, 10140, 10210,
11174, 11322, 11365, 11494, 12047, 13058, 13525, 13526, 13527, 13528,
13529, 13530, 13531, 13532, 13533, 13547, 13551, 13552, 13553, 13555,
13559, 13583, 13618, 13637, 13695, 13704, 13706, 13738, 13786
* ISO C11 support:

View File

@ -5790,6 +5790,15 @@ scalbn_test (void)
TEST_fi_f (scalbn, 1, 0L, 1);
TEST_fi_f (scalbn, 1, INT_MAX, plus_infty);
TEST_fi_f (scalbn, 1, INT_MIN, plus_zero);
TEST_fi_f (scalbn, max_value, INT_MAX, plus_infty);
TEST_fi_f (scalbn, max_value, INT_MIN, plus_zero);
TEST_fi_f (scalbn, min_value, INT_MAX, plus_infty);
TEST_fi_f (scalbn, min_value, INT_MIN, plus_zero);
TEST_fi_f (scalbn, min_value / 4, INT_MAX, plus_infty);
TEST_fi_f (scalbn, min_value / 4, INT_MIN, plus_zero);
END (scalbn);
}
@ -5812,6 +5821,35 @@ scalbln_test (void)
TEST_fl_f (scalbln, 1, 0L, 1);
TEST_fi_f (scalbln, 1, INT_MAX, plus_infty);
TEST_fi_f (scalbln, 1, INT_MIN, plus_zero);
TEST_fi_f (scalbln, max_value, INT_MAX, plus_infty);
TEST_fi_f (scalbln, max_value, INT_MIN, plus_zero);
TEST_fi_f (scalbln, min_value, INT_MAX, plus_infty);
TEST_fi_f (scalbln, min_value, INT_MIN, plus_zero);
TEST_fi_f (scalbln, min_value / 4, INT_MAX, plus_infty);
TEST_fi_f (scalbln, min_value / 4, INT_MIN, plus_zero);
TEST_fi_f (scalbln, 1, LONG_MAX, plus_infty);
TEST_fi_f (scalbln, 1, LONG_MIN, plus_zero);
TEST_fi_f (scalbln, max_value, LONG_MAX, plus_infty);
TEST_fi_f (scalbln, max_value, LONG_MIN, plus_zero);
TEST_fi_f (scalbln, min_value, LONG_MAX, plus_infty);
TEST_fi_f (scalbln, min_value, LONG_MIN, plus_zero);
TEST_fi_f (scalbln, min_value / 4, LONG_MAX, plus_infty);
TEST_fi_f (scalbln, min_value / 4, LONG_MIN, plus_zero);
#if LONG_MAX >= 0x100000000
TEST_fi_f (scalbln, 1, 0x88000000L, plus_infty);
TEST_fi_f (scalbln, 1, -0x88000000L, plus_zero);
TEST_fi_f (scalbln, max_value, 0x88000000L, plus_infty);
TEST_fi_f (scalbln, max_value, -0x88000000L, plus_zero);
TEST_fi_f (scalbln, min_value, 0x88000000L, plus_infty);
TEST_fi_f (scalbln, min_value, -0x88000000L, plus_zero);
TEST_fi_f (scalbln, min_value / 4, 0x88000000L, plus_infty);
TEST_fi_f (scalbln, min_value / 4, -0x88000000L, plus_zero);
#endif
END (scalbn);
}

View File

@ -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)

View File

@ -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)

View File

@ -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;}

View File

@ -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;}

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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 */

View File

@ -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 */

View File

@ -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)

View File

@ -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)