Fix ldbl-128 lrintl, lroundl missing exceptions for 32-bit long (bug 19085).

The ldbl-128 implementations of lrintl and lroundl miss "invalid"
exceptions on systems with 32-bit long for arguments that overflow
long but have exponent below 48.  This patch fixes this by rearranging
the sequence of tests in the code so the exponent < 48 case is only
used for exponents that don't overflow long.

Tested for mips64 (n32 and n64).

	[BZ #19085]
	* sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl): Move test for
	exponent below 48 inside case for non-overflowing exponent.
	* sysdeps/ieee754/ldbl-128/s_lroundl.c (__lroundl): Likewise.
This commit is contained in:
Joseph Myers 2015-10-07 16:10:59 +00:00
parent 7d6f9f74c8
commit 119d073e33
4 changed files with 30 additions and 23 deletions

View File

@ -1,3 +1,10 @@
2015-10-07 Joseph Myers <joseph@codesourcery.com>
[BZ #19085]
* sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl): Move test for
exponent below 48 inside case for non-overflowing exponent.
* sysdeps/ieee754/ldbl-128/s_lroundl.c (__lroundl): Likewise.
2015-10-07 Florian Weimer <fweimer@redhat.com>
* iconvdata/cp737.h (from_idx): Add const.

2
NEWS
View File

@ -18,7 +18,7 @@ Version 2.23
18820, 18823, 18824, 18825, 18857, 18863, 18870, 18872, 18873, 18875,
18887, 18921, 18951, 18952, 18956, 18961, 18966, 18967, 18969, 18970,
18977, 18980, 18981, 18985, 19003, 19012, 19016, 19018, 19032, 19046,
19049, 19050, 19059, 19071, 19076, 19077, 19078, 19079.
19049, 19050, 19059, 19071, 19076, 19077, 19078, 19079, 19085.
* The obsolete header <regexp.h> has been removed. Programs that require
this header must be updated to use <regex.h> instead.

View File

@ -45,20 +45,20 @@ __lrintl (long double x)
i0 &= 0x0000ffffffffffffLL;
i0 |= 0x0001000000000000LL;
if (j0 < 48)
if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
{
w = two112[sx] + x;
t = w - two112[sx];
GET_LDOUBLE_WORDS64 (i0, i1, t);
j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
i0 &= 0x0000ffffffffffffLL;
i0 |= 0x0001000000000000LL;
if (j0 < 48)
{
w = two112[sx] + x;
t = w - two112[sx];
GET_LDOUBLE_WORDS64 (i0, i1, t);
j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
i0 &= 0x0000ffffffffffffLL;
i0 |= 0x0001000000000000LL;
result = (j0 < 0 ? 0 : i0 >> (48 - j0));
}
else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
{
if (j0 >= 112)
result = (j0 < 0 ? 0 : i0 >> (48 - j0));
}
else if (j0 >= 112)
result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
else
{

View File

@ -37,19 +37,19 @@ __lroundl (long double x)
i0 &= 0x0000ffffffffffffLL;
i0 |= 0x0001000000000000LL;
if (j0 < 48)
if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
{
if (j0 < 0)
return j0 < -1 ? 0 : sign;
else
if (j0 < 48)
{
i0 += 0x0000800000000000LL >> j0;
result = i0 >> (48 - j0);
if (j0 < 0)
return j0 < -1 ? 0 : sign;
else
{
i0 += 0x0000800000000000LL >> j0;
result = i0 >> (48 - j0);
}
}
}
else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
{
if (j0 >= 112)
else if (j0 >= 112)
result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
else
{