Fix fdim handling of infinities (bug 15797).

This commit is contained in:
Joseph Myers 2013-08-21 19:56:48 +00:00
parent c0c3f78afb
commit acd06bb11f
6 changed files with 51 additions and 37 deletions

View file

@ -1,3 +1,13 @@
2013-08-21 Joseph Myers <joseph@codesourcery.com>
[BZ #15797]
* math/s_fdim.c (__fdim): Check for infinite arguments if result
is infinite, not alongside NaN test.
* math/s_fdimf.c (__fdimf): Likewise.
* math/s_fdiml.c (__fdiml): Likewise.
* math/libm-test.inc (fdim_test_data): Add more tests. Test that
errno is unchanged.
2013-08-21 Ondřej Bílka <neleai@seznam.cz>
* argp/argp-help.c: Fix typos.

2
NEWS
View file

@ -9,7 +9,7 @@ Version 2.19
* The following bugs are resolved with this release:
14699, 15531, 15749
14699, 15531, 15749, 15797
* CVE-2013-4237 The readdir_r function could write more than NAME_MAX bytes
to the d_name member of struct dirent, or omit the terminating NUL

View file

@ -8144,33 +8144,37 @@ fabs_test (void)
static const struct test_ff_f_data fdim_test_data[] =
{
TEST_ff_f (fdim, 0, 0, 0, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, 9, 0, 9, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, 0, 9, 0, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, -9, 0, 0, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, 0, -9, 9, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, 0, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, 9, 0, 9, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, 0, 9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, -9, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, 0, -9, 9, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, plus_infty, 9, plus_infty, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, plus_infty, -9, plus_infty, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, minus_infty, 9, 0, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, minus_infty, -9, 0, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, 9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, -9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, 9, plus_infty, 0, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, -9, plus_infty, 0, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, plus_infty, 9, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, plus_infty, -9, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, minus_infty, 9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, minus_infty, -9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, 9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, -9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, 9, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, -9, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, 9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, -9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, qnan_value, 9, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, qnan_value, -9, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, 9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, -9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, qnan_value, 9, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, qnan_value, -9, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, plus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION),
TEST_ff_f (fdim, plus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, plus_infty, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, minus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fdim, minus_infty, minus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
};
static void

View file

@ -26,16 +26,16 @@ __fdim (double x, double y)
int clsx = fpclassify (x);
int clsy = fpclassify (y);
if (clsx == FP_NAN || clsy == FP_NAN
|| (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE))
/* Raise invalid flag. */
if (clsx == FP_NAN || clsy == FP_NAN)
/* Raise invalid flag for signaling but not quiet NaN. */
return x - y;
if (x <= y)
return 0.0;
double r = x - y;
if (fpclassify (r) == FP_INFINITE)
if (fpclassify (r) == FP_INFINITE
&& clsx != FP_INFINITE && clsy != FP_INFINITE)
__set_errno (ERANGE);
return r;

View file

@ -26,16 +26,16 @@ __fdimf (float x, float y)
int clsx = fpclassify (x);
int clsy = fpclassify (y);
if (clsx == FP_NAN || clsy == FP_NAN
|| (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE))
/* Raise invalid flag. */
if (clsx == FP_NAN || clsy == FP_NAN)
/* Raise invalid flag for signaling but not quiet NaN. */
return x - y;
if (x <= y)
return 0.0f;
float r = x - y;
if (fpclassify (r) == FP_INFINITE)
if (fpclassify (r) == FP_INFINITE
&& clsx != FP_INFINITE && clsy != FP_INFINITE)
__set_errno (ERANGE);
return r;

View file

@ -26,16 +26,16 @@ __fdiml (long double x, long double y)
int clsx = fpclassify (x);
int clsy = fpclassify (y);
if (clsx == FP_NAN || clsy == FP_NAN
|| (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE))
/* Raise invalid flag. */
if (clsx == FP_NAN || clsy == FP_NAN)
/* Raise invalid flag for signaling but not quiet NaN. */
return x - y;
if (x <= y)
return 0.0f;
long double r = x - y;
if (fpclassify (r) == FP_INFINITE)
if (fpclassify (r) == FP_INFINITE
&& clsx != FP_INFINITE && clsy != FP_INFINITE)
__set_errno (ERANGE);
return r;