forked from rpms/glibc
strtod: Fix subnormal rounding & errno; add new tests (RHEL-46739)
Resolves: RHEL-46739
This commit is contained in:
parent
52c06307bd
commit
66024333e7
49
glibc-RHEL-46739-1.patch
Normal file
49
glibc-RHEL-46739-1.patch
Normal file
@ -0,0 +1,49 @@
|
||||
commit 207d64feb26279e152c50744e3c37e68491aca99
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Wed Aug 14 17:15:46 2024 +0000
|
||||
|
||||
Test errno setting on strtod overflow in tst-strtod-round
|
||||
|
||||
We have no tests that errno is set to ERANGE on overflow of
|
||||
strtod-family functions (we do have some tests for underflow, in
|
||||
tst-strtod-underflow). Add such tests to tst-strtod-round.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod-round-skeleton.c b/stdlib/tst-strtod-round-skeleton.c
|
||||
index f60b9a00e9e8d262..1ff1977112bda7a8 100644
|
||||
--- a/stdlib/tst-strtod-round-skeleton.c
|
||||
+++ b/stdlib/tst-strtod-round-skeleton.c
|
||||
@@ -21,6 +21,7 @@
|
||||
declared in the headers. */
|
||||
#define _LIBC_TEST 1
|
||||
#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
+#include <errno.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@@ -205,7 +206,9 @@ struct test {
|
||||
#define GEN_ONE_TEST(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
{ \
|
||||
feclearexcept (FE_ALL_EXCEPT); \
|
||||
+ errno = 0; \
|
||||
FTYPE f = STRTO (FSUF) (s, NULL); \
|
||||
+ int new_errno = errno; \
|
||||
if (f != expected->FSUF \
|
||||
|| (copysign ## CSUF) (1.0 ## LSUF, f) \
|
||||
!= (copysign ## CSUF) (1.0 ## LSUF, expected->FSUF)) \
|
||||
@@ -254,6 +257,14 @@ struct test {
|
||||
printf ("ignoring this exception error\n"); \
|
||||
} \
|
||||
} \
|
||||
+ if (overflow->FSUF && new_errno != ERANGE) \
|
||||
+ { \
|
||||
+ printf (FNPFXS "to" #FSUF \
|
||||
+ " (" STRM ") left errno == %d," \
|
||||
+ " not %d (ERANGE)\n", \
|
||||
+ s, new_errno, ERANGE); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
} \
|
||||
}
|
||||
|
38
glibc-RHEL-46739-10.patch
Normal file
38
glibc-RHEL-46739-10.patch
Normal file
@ -0,0 +1,38 @@
|
||||
commit 378039ca578c2ea93095a1e710d96f58c68a3997
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:24:45 2024 +0000
|
||||
|
||||
Add tests of more strtod special cases
|
||||
|
||||
There is very little test coverage of inputs to strtod-family
|
||||
functions that don't contain anything that can be parsed as a number
|
||||
(one test of ".y" in tst-strtod2), and none that I can see of skipping
|
||||
initial whitespace. Add some tests of these things to tst-strtod2.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c
|
||||
index c84bd792c1a3f511..d00bc13323c50622 100644
|
||||
--- a/stdlib/tst-strtod2.c
|
||||
+++ b/stdlib/tst-strtod2.c
|
||||
@@ -31,6 +31,20 @@ struct test_strto ## FSUF \
|
||||
{ "0x1px", 1.0 ## LSUF, 3 }, \
|
||||
{ "0x1p+x", 1.0 ## LSUF, 3 }, \
|
||||
{ "0x1p-x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "", 0.0 ## LSUF, 0 }, \
|
||||
+ { ".", 0.0 ## LSUF, 0 }, \
|
||||
+ { "-", 0.0 ## LSUF, 0 }, \
|
||||
+ { "-.", 0.0 ## LSUF, 0 }, \
|
||||
+ { ".e", 0.0 ## LSUF, 0 }, \
|
||||
+ { "-.e", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t.", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t-", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t-.", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t.e", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t-.e", 0.0 ## LSUF, 0 }, \
|
||||
+ { " \t\f\r\n\v1", 1.0 ## LSUF, 7 }, \
|
||||
+ { " \t\f\r\n\v-1.5e2", -150.0 ## LSUF, 12 }, \
|
||||
{ "INFx", INFINITY, 3 }, \
|
||||
{ "infx", INFINITY, 3 }, \
|
||||
{ "INFINITx", INFINITY, 3 }, \
|
439
glibc-RHEL-46739-11.patch
Normal file
439
glibc-RHEL-46739-11.patch
Normal file
@ -0,0 +1,439 @@
|
||||
commit 94ca2c0894f0e1b62625c369cc598a2b9236622c
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:25:32 2024 +0000
|
||||
|
||||
Make tst-strtod-underflow type-generic
|
||||
|
||||
The test tst-strtod-underflow covers various edge cases close to the
|
||||
underflow threshold for strtod (especially cases where underflow on
|
||||
architectures with after-rounding tininess detection depends on the
|
||||
rounding mode). Make it use the type-generic machinery, with
|
||||
corresponding test inputs for each supported floating-point format, so
|
||||
that other functions in the strtod family are tested for underflow
|
||||
edge cases as well.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod-underflow.c b/stdlib/tst-strtod-underflow.c
|
||||
index 294f88de439fb3e7..094a70bbbe53e70b 100644
|
||||
--- a/stdlib/tst-strtod-underflow.c
|
||||
+++ b/stdlib/tst-strtod-underflow.c
|
||||
@@ -17,6 +17,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* Defining _LIBC_TEST ensures long double math functions are
|
||||
+ declared in the headers. */
|
||||
+#define _LIBC_TEST 1
|
||||
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
#include <errno.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
@@ -25,6 +29,60 @@
|
||||
#include <stdlib.h>
|
||||
#include <tininess.h>
|
||||
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+/* Logic for selecting between tests for different formats is as in
|
||||
+ tst-strtod-skeleton.c, but here it is selecting string inputs with
|
||||
+ different underflow properties, rather than generated test
|
||||
+ data. */
|
||||
+
|
||||
+#define _CONCAT(a, b) a ## b
|
||||
+#define CONCAT(a, b) _CONCAT (a, b)
|
||||
+
|
||||
+#define MEMBER(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+ const char *s_ ## FSUF;
|
||||
+
|
||||
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
+# define CHOOSE_ld(f,d,...) d
|
||||
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381
|
||||
+# define CHOOSE_ld(f,d,ld64i,...) ld64i
|
||||
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16382
|
||||
+# define CHOOSE_ld(f,d,ld64i,ld64m,...) ld64m
|
||||
+#elif LDBL_MANT_DIG == 106 && LDBL_MAX_EXP == 1024
|
||||
+# define CHOOSE_ld(f,d,ld64i,ld64m,ld106,...) ld106
|
||||
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
|
||||
+# define CHOOSE_ld(f,d,ld64i,ld64m,ld106,ld113,...) ld113
|
||||
+#else
|
||||
+# error "unknown long double format"
|
||||
+#endif
|
||||
+
|
||||
+#define CHOOSE_f(f,...) f
|
||||
+#define CHOOSE_f32(f,...) f
|
||||
+#define CHOOSE_d(f,d,...) d
|
||||
+#define CHOOSE_f64(f,d,...) d
|
||||
+#define CHOOSE_f32x(f,d,...) d
|
||||
+#define CHOOSE_f128(f,d,ld64i,ld64m,ld106,ld113,...) ld113
|
||||
+
|
||||
+#if __HAVE_FLOAT64X
|
||||
+# if FLT64X_MANT_DIG == 113 && FLT64X_MAX_EXP == 16384
|
||||
+# define CHOOSE_f64x(f,d,ld64i,ld64m,ld106,ld113,...) ld113
|
||||
+# elif (FLT64X_MANT_DIG == 64 \
|
||||
+ && FLT64X_MAX_EXP == 16384 \
|
||||
+ && FLT64X_MIN_EXP == -16381)
|
||||
+# define CHOOSE_f64x(f,d,ld64i,...) ld64i
|
||||
+# else
|
||||
+# error "unknown _Float64x format"
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
+#define _XNTRY(FSUF, FTYPE, FTOSTR, LSUF, CSUF, ...) \
|
||||
+ CHOOSE_ ## FSUF (__VA_ARGS__),
|
||||
+#define XNTRY(...) \
|
||||
+ GEN_TEST_STRTOD_FOREACH (_XNTRY, __VA_ARGS__)
|
||||
+
|
||||
+#define TEST(f, d, ld64i, ld64m, ld106, ld113, u) \
|
||||
+ { XNTRY(f, d, ld64i, ld64m, ld106, ld113) u }
|
||||
+
|
||||
enum underflow_case
|
||||
{
|
||||
/* Result is exact or outside the subnormal range. */
|
||||
@@ -55,38 +113,194 @@ enum underflow_case
|
||||
|
||||
struct test
|
||||
{
|
||||
- const char *s;
|
||||
+ GEN_TEST_STRTOD_FOREACH (MEMBER)
|
||||
enum underflow_case c;
|
||||
};
|
||||
|
||||
static const struct test tests[] =
|
||||
{
|
||||
- { "0x1p-1022", UNDERFLOW_NONE },
|
||||
- { "-0x1p-1022", UNDERFLOW_NONE },
|
||||
- { "0x0p-10000000000000000000000000", UNDERFLOW_NONE },
|
||||
- { "-0x0p-10000000000000000000000000", UNDERFLOW_NONE },
|
||||
- { "0x1p-10000000000000000000000000", UNDERFLOW_ALWAYS },
|
||||
- { "-0x1p-10000000000000000000000000", UNDERFLOW_ALWAYS },
|
||||
- { "0x1.000000000000000000001p-1022", UNDERFLOW_NONE },
|
||||
- { "-0x1.000000000000000000001p-1022", UNDERFLOW_NONE },
|
||||
- { "0x1p-1075", UNDERFLOW_ALWAYS },
|
||||
- { "-0x1p-1075", UNDERFLOW_ALWAYS },
|
||||
- { "0x1p-1023", UNDERFLOW_NONE },
|
||||
- { "-0x1p-1023", UNDERFLOW_NONE },
|
||||
- { "0x1p-1074", UNDERFLOW_NONE },
|
||||
- { "-0x1p-1074", UNDERFLOW_NONE },
|
||||
- { "0x1.ffffffffffffep-1023", UNDERFLOW_NONE },
|
||||
- { "-0x1.ffffffffffffep-1023", UNDERFLOW_NONE },
|
||||
- { "0x1.fffffffffffffp-1023", UNDERFLOW_ALWAYS },
|
||||
- { "-0x1.fffffffffffffp-1023", UNDERFLOW_ALWAYS },
|
||||
- { "0x1.fffffffffffff0001p-1023", UNDERFLOW_EXCEPT_UPWARD },
|
||||
- { "-0x1.fffffffffffff0001p-1023", UNDERFLOW_EXCEPT_DOWNWARD },
|
||||
- { "0x1.fffffffffffff7fffp-1023", UNDERFLOW_EXCEPT_UPWARD },
|
||||
- { "-0x1.fffffffffffff7fffp-1023", UNDERFLOW_EXCEPT_DOWNWARD },
|
||||
- { "0x1.fffffffffffff8p-1023", UNDERFLOW_ONLY_DOWNWARD_ZERO },
|
||||
- { "-0x1.fffffffffffff8p-1023", UNDERFLOW_ONLY_UPWARD_ZERO },
|
||||
- { "0x1.fffffffffffffffffp-1023", UNDERFLOW_ONLY_DOWNWARD_ZERO },
|
||||
- { "-0x1.fffffffffffffffffp-1023", UNDERFLOW_ONLY_UPWARD_ZERO },
|
||||
+ TEST ("0x1p-126",
|
||||
+ "0x1p-1022",
|
||||
+ "0x1p-16382",
|
||||
+ "0x1p-16383",
|
||||
+ "0x1p-969",
|
||||
+ "0x1p-16382",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1p-126",
|
||||
+ "-0x1p-1022",
|
||||
+ "-0x1p-16382",
|
||||
+ "-0x1p-16383",
|
||||
+ "-0x1p-969",
|
||||
+ "-0x1p-16382",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ "0x0p-10000000000000000000000000",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ "-0x0p-10000000000000000000000000",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ "0x1p-10000000000000000000000000",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ "-0x1p-10000000000000000000000000",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("0x1.000000000000000000001p-126",
|
||||
+ "0x1.000000000000000000001p-1022",
|
||||
+ "0x1.000000000000000000001p-16382",
|
||||
+ "0x1.000000000000000000001p-16383",
|
||||
+ "0x1.000000000000000000001p-969",
|
||||
+ "0x1.00000000000000000000000000000000000000001p-16382",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1.000000000000000000001p-126",
|
||||
+ "-0x1.000000000000000000001p-1022",
|
||||
+ "-0x1.000000000000000000001p-16382",
|
||||
+ "-0x1.000000000000000000001p-16383",
|
||||
+ "-0x1.000000000000000000001p-969",
|
||||
+ "-0x1.00000000000000000000000000000000000000001p-16382",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1p-150",
|
||||
+ "0x1p-1075",
|
||||
+ "0x1p-16446",
|
||||
+ "0x1p-16447",
|
||||
+ "0x1p-1075",
|
||||
+ "0x1p-16495",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("-0x1p-150",
|
||||
+ "-0x1p-1075",
|
||||
+ "-0x1p-16446",
|
||||
+ "-0x1p-16447",
|
||||
+ "-0x1p-1075",
|
||||
+ "-0x1p-16495",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("0x1p-127",
|
||||
+ "0x1p-1023",
|
||||
+ "0x1p-16383",
|
||||
+ "0x1p-16384",
|
||||
+ "0x1p-970",
|
||||
+ "0x1p-16383",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1p-127",
|
||||
+ "-0x1p-1023",
|
||||
+ "-0x1p-16383",
|
||||
+ "-0x1p-16384",
|
||||
+ "-0x1p-970",
|
||||
+ "-0x1p-16383",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1p-149",
|
||||
+ "0x1p-1074",
|
||||
+ "0x1p-16445",
|
||||
+ "0x1p-16446",
|
||||
+ "0x1p-1074",
|
||||
+ "0x1p-16494",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1p-149",
|
||||
+ "-0x1p-1074",
|
||||
+ "-0x1p-16445",
|
||||
+ "-0x1p-16446",
|
||||
+ "-0x1p-1074",
|
||||
+ "-0x1p-16494",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1.fffffcp-127",
|
||||
+ "0x1.ffffffffffffep-1023",
|
||||
+ "0x1.fffffffffffffffcp-16383",
|
||||
+ "0x1.fffffffffffffffcp-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffffp-970",
|
||||
+ "0x1.fffffffffffffffffffffffffffep-16383",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("-0x1.fffffcp-127",
|
||||
+ "-0x1.ffffffffffffep-1023",
|
||||
+ "-0x1.fffffffffffffffcp-16383",
|
||||
+ "-0x1.fffffffffffffffcp-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffffp-970",
|
||||
+ "-0x1.fffffffffffffffffffffffffffep-16383",
|
||||
+ UNDERFLOW_NONE),
|
||||
+ TEST ("0x1.fffffep-127",
|
||||
+ "0x1.fffffffffffffp-1023",
|
||||
+ "0x1.fffffffffffffffep-16383",
|
||||
+ "0x1.fffffffffffffffep-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffff8p-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffffp-16383",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("-0x1.fffffep-127",
|
||||
+ "-0x1.fffffffffffffp-1023",
|
||||
+ "-0x1.fffffffffffffffep-16383",
|
||||
+ "-0x1.fffffffffffffffep-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffff8p-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffffp-16383",
|
||||
+ UNDERFLOW_ALWAYS),
|
||||
+ TEST ("0x1.fffffe0001p-127",
|
||||
+ "0x1.fffffffffffff0001p-1023",
|
||||
+ "0x1.fffffffffffffffe0001p-16383",
|
||||
+ "0x1.fffffffffffffffe0001p-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffff80001p-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffff0001p-16383",
|
||||
+ UNDERFLOW_EXCEPT_UPWARD),
|
||||
+ TEST ("-0x1.fffffe0001p-127",
|
||||
+ "-0x1.fffffffffffff0001p-1023",
|
||||
+ "-0x1.fffffffffffffffe0001p-16383",
|
||||
+ "-0x1.fffffffffffffffe0001p-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffff80001p-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffff0001p-16383",
|
||||
+ UNDERFLOW_EXCEPT_DOWNWARD),
|
||||
+ TEST ("0x1.fffffeffffp-127",
|
||||
+ "0x1.fffffffffffff7fffp-1023",
|
||||
+ "0x1.fffffffffffffffeffffp-16383",
|
||||
+ "0x1.fffffffffffffffeffffp-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffffbffffp-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffff7fffp-16383",
|
||||
+ UNDERFLOW_EXCEPT_UPWARD),
|
||||
+ TEST ("-0x1.fffffeffffp-127",
|
||||
+ "-0x1.fffffffffffff7fffp-1023",
|
||||
+ "-0x1.fffffffffffffffeffffp-16383",
|
||||
+ "-0x1.fffffffffffffffeffffp-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffffbffffp-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffff7fffp-16383",
|
||||
+ UNDERFLOW_EXCEPT_DOWNWARD),
|
||||
+ TEST ("0x1.ffffffp-127",
|
||||
+ "0x1.fffffffffffff8p-1023",
|
||||
+ "0x1.ffffffffffffffffp-16383",
|
||||
+ "0x1.ffffffffffffffffp-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffffcp-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffff8p-16383",
|
||||
+ UNDERFLOW_ONLY_DOWNWARD_ZERO),
|
||||
+ TEST ("-0x1.ffffffp-127",
|
||||
+ "-0x1.fffffffffffff8p-1023",
|
||||
+ "-0x1.ffffffffffffffffp-16383",
|
||||
+ "-0x1.ffffffffffffffffp-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffffcp-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffff8p-16383",
|
||||
+ UNDERFLOW_ONLY_UPWARD_ZERO),
|
||||
+ TEST ("0x1.ffffffffffp-127",
|
||||
+ "0x1.fffffffffffffffffp-1023",
|
||||
+ "0x1.ffffffffffffffffffffp-16383",
|
||||
+ "0x1.ffffffffffffffffffffp-16384",
|
||||
+ "0x1.ffffffffffffffffffffffffffffffp-970",
|
||||
+ "0x1.ffffffffffffffffffffffffffffffffp-16383",
|
||||
+ UNDERFLOW_ONLY_DOWNWARD_ZERO),
|
||||
+ TEST ("-0x1.ffffffffffp-127",
|
||||
+ "-0x1.fffffffffffffffffp-1023",
|
||||
+ "-0x1.ffffffffffffffffffffp-16383",
|
||||
+ "-0x1.ffffffffffffffffffffp-16384",
|
||||
+ "-0x1.ffffffffffffffffffffffffffffffp-970",
|
||||
+ "-0x1.ffffffffffffffffffffffffffffffffp-16383",
|
||||
+ UNDERFLOW_ONLY_UPWARD_ZERO),
|
||||
};
|
||||
|
||||
/* Return whether to expect underflow from a particular testcase, in a
|
||||
@@ -133,39 +347,62 @@ static bool support_underflow_exception = false;
|
||||
volatile double d = DBL_MIN;
|
||||
volatile double dd;
|
||||
|
||||
-static int
|
||||
-test_in_one_mode (const char *s, enum underflow_case c, int rm,
|
||||
- const char *mode_name)
|
||||
+static bool
|
||||
+test_got_fe_underflow (void)
|
||||
{
|
||||
- int result = 0;
|
||||
- feclearexcept (FE_ALL_EXCEPT);
|
||||
- errno = 0;
|
||||
- double d = strtod (s, NULL);
|
||||
- int got_errno = errno;
|
||||
#ifdef FE_UNDERFLOW
|
||||
- bool got_fe_underflow = fetestexcept (FE_UNDERFLOW) != 0;
|
||||
+ return fetestexcept (FE_UNDERFLOW) != 0;
|
||||
#else
|
||||
- bool got_fe_underflow = false;
|
||||
+ return false;
|
||||
#endif
|
||||
- printf ("strtod (%s) (%s) returned %a, errno = %d, %sunderflow exception\n",
|
||||
- s, mode_name, d, got_errno, got_fe_underflow ? "" : "no ");
|
||||
- bool this_expect_underflow = expect_underflow (c, rm);
|
||||
- if (got_errno != 0 && got_errno != ERANGE)
|
||||
- {
|
||||
- puts ("FAIL: errno neither 0 nor ERANGE");
|
||||
- result = 1;
|
||||
- }
|
||||
- else if (this_expect_underflow != (errno == ERANGE))
|
||||
- {
|
||||
- puts ("FAIL: underflow from errno differs from expectations");
|
||||
- result = 1;
|
||||
- }
|
||||
- if (support_underflow_exception && got_fe_underflow != this_expect_underflow)
|
||||
- {
|
||||
- puts ("FAIL: underflow from exceptions differs from expectations");
|
||||
- result = 1;
|
||||
- }
|
||||
- return result;
|
||||
+}
|
||||
+
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static int \
|
||||
+test_strto ## FSUF (int i, int rm, const char *mode_name) \
|
||||
+{ \
|
||||
+ const char *s = tests[i].s_ ## FSUF; \
|
||||
+ enum underflow_case c = tests[i].c; \
|
||||
+ int result = 0; \
|
||||
+ feclearexcept (FE_ALL_EXCEPT); \
|
||||
+ errno = 0; \
|
||||
+ FTYPE d = strto ## FSUF (s, NULL); \
|
||||
+ int got_errno = errno; \
|
||||
+ bool got_fe_underflow = test_got_fe_underflow (); \
|
||||
+ char buf[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf, sizeof (buf), "%a", d); \
|
||||
+ printf ("strto" #FSUF \
|
||||
+ " (%s) (%s) returned %s, errno = %d, " \
|
||||
+ "%sunderflow exception\n", \
|
||||
+ s, mode_name, buf, got_errno, \
|
||||
+ got_fe_underflow ? "" : "no "); \
|
||||
+ bool this_expect_underflow = expect_underflow (c, rm); \
|
||||
+ if (got_errno != 0 && got_errno != ERANGE) \
|
||||
+ { \
|
||||
+ puts ("FAIL: errno neither 0 nor ERANGE"); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ else if (this_expect_underflow != (errno == ERANGE)) \
|
||||
+ { \
|
||||
+ puts ("FAIL: underflow from errno differs from expectations"); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ if (support_underflow_exception \
|
||||
+ && got_fe_underflow != this_expect_underflow) \
|
||||
+ { \
|
||||
+ puts ("FAIL: underflow from exceptions " \
|
||||
+ "differs from expectations"); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ return result; \
|
||||
+}
|
||||
+
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
+
|
||||
+static int
|
||||
+test_in_one_mode (size_t i, int rm, const char *mode_name)
|
||||
+{
|
||||
+ return STRTOD_TEST_FOREACH (test_strto, i, rm, mode_name);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -191,12 +428,12 @@ do_test (void)
|
||||
#endif
|
||||
for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
|
||||
{
|
||||
- result |= test_in_one_mode (tests[i].s, tests[i].c, fe_tonearest,
|
||||
+ result |= test_in_one_mode (i, fe_tonearest,
|
||||
"default rounding mode");
|
||||
#ifdef FE_DOWNWARD
|
||||
if (!fesetround (FE_DOWNWARD))
|
||||
{
|
||||
- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_DOWNWARD,
|
||||
+ result |= test_in_one_mode (i, FE_DOWNWARD,
|
||||
"FE_DOWNWARD");
|
||||
fesetround (save_round_mode);
|
||||
}
|
||||
@@ -204,7 +441,7 @@ do_test (void)
|
||||
#ifdef FE_TOWARDZERO
|
||||
if (!fesetround (FE_TOWARDZERO))
|
||||
{
|
||||
- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_TOWARDZERO,
|
||||
+ result |= test_in_one_mode (i, FE_TOWARDZERO,
|
||||
"FE_TOWARDZERO");
|
||||
fesetround (save_round_mode);
|
||||
}
|
||||
@@ -212,7 +449,7 @@ do_test (void)
|
||||
#ifdef FE_UPWARD
|
||||
if (!fesetround (FE_UPWARD))
|
||||
{
|
||||
- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_UPWARD,
|
||||
+ result |= test_in_one_mode (i, FE_UPWARD,
|
||||
"FE_UPWARD");
|
||||
fesetround (save_round_mode);
|
||||
}
|
16723
glibc-RHEL-46739-2.patch
Normal file
16723
glibc-RHEL-46739-2.patch
Normal file
File diff suppressed because it is too large
Load Diff
445
glibc-RHEL-46739-3.patch
Normal file
445
glibc-RHEL-46739-3.patch
Normal file
@ -0,0 +1,445 @@
|
||||
commit 457622c2fa8f9f7435822d5287a437bc8be8090d
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Tue Aug 27 12:41:02 2024 +0000
|
||||
|
||||
Fix strtod subnormal rounding (bug 30220)
|
||||
|
||||
As reported in bug 30220, the implementation of strtod-family
|
||||
functions has a bug in the following case: the input string would,
|
||||
with infinite exponent range, take one more bit to represent than is
|
||||
available in the normal precision of the return type; the value
|
||||
represented is in the subnormal range; and there are no nonzero bits
|
||||
in the value, below those that can be represented in subnormal
|
||||
precision, other than the least significant bit and possibly the
|
||||
0.5ulp bit. In this case, round_and_return ends up discarding the
|
||||
least significant bit.
|
||||
|
||||
Fix by saving that bit to merge into more_bits (it can't be merged in
|
||||
at the time it's computed, because more_bits mustn't include this bit
|
||||
in the case of after-rounding tininess detection checking if the
|
||||
result is still subnormal when rounded to normal precision, so merging
|
||||
this bit into more_bits needs to take place after that check).
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
|
||||
index 5a54d99ae8663641..49b88e9a86be8441 100644
|
||||
--- a/stdlib/strtod_l.c
|
||||
+++ b/stdlib/strtod_l.c
|
||||
@@ -223,6 +223,7 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
|
||||
|
||||
mp_size_t shift = MIN_EXP - 1 - exponent;
|
||||
bool is_tiny = true;
|
||||
+ bool old_half_bit = (round_limb & (((mp_limb_t) 1) << round_bit)) != 0;
|
||||
|
||||
more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0;
|
||||
if (shift == MANT_DIG)
|
||||
@@ -293,6 +294,7 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
|
||||
round_bit = shift - 1;
|
||||
(void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, shift);
|
||||
}
|
||||
+ more_bits |= old_half_bit;
|
||||
/* This is a hook for the m68k long double format, where the
|
||||
exponent bias is the same for normalized and denormalized
|
||||
numbers. */
|
||||
diff --git a/stdlib/tst-strtod-round-data b/stdlib/tst-strtod-round-data
|
||||
index 84ab705709b24b6c..9489fbcc9ce7eee2 100644
|
||||
--- a/stdlib/tst-strtod-round-data
|
||||
+++ b/stdlib/tst-strtod-round-data
|
||||
@@ -265,3 +265,15 @@
|
||||
1.000000000000000000000000000000000385185988877447170611195588516985463707620329643077639047987759113311767578125
|
||||
1.0000000000000000000000000000000001925929944387235853055977942584927318538101648215388195239938795566558837890625
|
||||
1.00000000000000000000000000000000009629649721936179265279889712924636592690508241076940976199693977832794189453125
|
||||
+0x30000002222225p-1077
|
||||
+0x0.7fffffffffffeap-1022
|
||||
+0x0.7fffffffffffe9p-1022
|
||||
+0x0.7ffffd4p-126
|
||||
+0x0.7ffffffffffffffd4p-16382
|
||||
+0x0.7ffffffffffffffd4p-16383
|
||||
+0x0.7ffffffffffffffffffffffffffeap-16382
|
||||
+0x0.7000004p-126
|
||||
+0x0.70000000000002p-1022
|
||||
+0x0.70000000000000004p-16382
|
||||
+0x0.70000000000000004p-16383
|
||||
+0x0.70000000000000000000000000002p-16382
|
||||
diff --git a/stdlib/tst-strtod-round-data.h b/stdlib/tst-strtod-round-data.h
|
||||
index 13e62dd2b0588a16..ed50eb2537bc175c 100644
|
||||
--- a/stdlib/tst-strtod-round-data.h
|
||||
+++ b/stdlib/tst-strtod-round-data.h
|
||||
@@ -15437,4 +15437,376 @@ static const struct test tests[] = {
|
||||
0x1p+0, false, false,
|
||||
0x1p+0, false, false,
|
||||
0x1.0000000000000000000000000001p+0, false, false),
|
||||
+ TEST ("0x30000002222225p-1077",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x1.800000111111p-1024, false, true,
|
||||
+ 0x1.8000001111114p-1024, false, true,
|
||||
+ 0x1.800000111111p-1024, false, true,
|
||||
+ 0x1.8000001111114p-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ true,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ false,
|
||||
+ 0x1.800000111111p-1024, false, true,
|
||||
+ 0x1.8000001111114p-1024, false, true,
|
||||
+ 0x1.800000111111p-1024, false, true,
|
||||
+ 0x1.8000001111114p-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false,
|
||||
+ 0x1.80000011111128p-1024, false, false),
|
||||
+ TEST ("0x0.7fffffffffffeap-1022",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ false,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa8p-1024, false, false),
|
||||
+ TEST ("0x0.7fffffffffffe9p-1022",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ false,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ 0x1.ffffffffffff8p-1024, false, true,
|
||||
+ 0x1.ffffffffffffcp-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false,
|
||||
+ 0x1.ffffffffffffa4p-1024, false, false),
|
||||
+ TEST ("0x0.7ffffd4p-126",
|
||||
+ false,
|
||||
+ 0x1.fffffp-128, false, true,
|
||||
+ 0x1.fffff8p-128, false, true,
|
||||
+ 0x1.fffffp-128, false, true,
|
||||
+ 0x1.fffff8p-128, false, true,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false,
|
||||
+ 0x1.fffff5p-128, false, false),
|
||||
+ TEST ("0x0.7ffffffffffffffd4p-16382",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffffp-16384, false, true,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ 0x1.fffffffffffffffp-16384, false, true,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffff4p-16384, false, true,
|
||||
+ 0x1.fffffffffffffff4p-16384, false, true,
|
||||
+ 0x1.fffffffffffffff4p-16384, false, true,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ true,
|
||||
+ 0x1.fffffffffffffff5p-16384, false, false,
|
||||
+ 0x1.fffffffffffffff5p-16384, false, false,
|
||||
+ 0x1.fffffffffffffff5p-16384, false, false,
|
||||
+ 0x1.fffffffffffffff5p-16384, false, false),
|
||||
+ TEST ("0x0.7ffffffffffffffd4p-16383",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0x1p-16384, false, true,
|
||||
+ false,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0xf.ffffffffffffffcp-16388, false, true,
|
||||
+ 0xf.ffffffffffffff8p-16388, false, true,
|
||||
+ 0xf.ffffffffffffffcp-16388, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ true,
|
||||
+ 0xf.ffffffffffffffa8p-16388, false, false,
|
||||
+ 0xf.ffffffffffffffa8p-16388, false, false,
|
||||
+ 0xf.ffffffffffffffa8p-16388, false, false,
|
||||
+ 0xf.ffffffffffffffa8p-16388, false, false),
|
||||
+ TEST ("0x0.7ffffffffffffffffffffffffffeap-16382",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ 0x2p-16384, false, true,
|
||||
+ 0x1.fffffffffffffff8p-16384, false, true,
|
||||
+ 0x2p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffffcp-16384, false, true,
|
||||
+ 0x2p-16384, false, true,
|
||||
+ 0x1.fffffffffffffffcp-16384, false, true,
|
||||
+ 0x2p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.fffffffffffffffffffffffffff8p-16384, false, true,
|
||||
+ 0x1.fffffffffffffffffffffffffffcp-16384, false, true,
|
||||
+ 0x1.fffffffffffffffffffffffffff8p-16384, false, true,
|
||||
+ 0x1.fffffffffffffffffffffffffffcp-16384, false, true),
|
||||
+ TEST ("0x0.7000004p-126",
|
||||
+ false,
|
||||
+ 0x1.cp-128, false, true,
|
||||
+ 0x1.cp-128, false, true,
|
||||
+ 0x1.cp-128, false, true,
|
||||
+ 0x1.c00008p-128, false, true,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ true,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false,
|
||||
+ 0x1.c00001p-128, false, false),
|
||||
+ TEST ("0x0.70000000000002p-1022",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.c000000000004p-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ true,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ false,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.cp-1024, false, true,
|
||||
+ 0x1.c000000000004p-1024, false, true,
|
||||
+ true,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false,
|
||||
+ 0x1.c0000000000008p-1024, false, false),
|
||||
+ TEST ("0x0.70000000000000004p-16382",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000008p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000004p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ true,
|
||||
+ 0x1.c000000000000001p-16384, false, false,
|
||||
+ 0x1.c000000000000001p-16384, false, false,
|
||||
+ 0x1.c000000000000001p-16384, false, false,
|
||||
+ 0x1.c000000000000001p-16384, false, false),
|
||||
+ TEST ("0x0.70000000000000004p-16383",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xe.000000000000008p-16388, false, true,
|
||||
+ false,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xep-16388, false, true,
|
||||
+ 0xe.000000000000004p-16388, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ true,
|
||||
+ 0xe.0000000000000008p-16388, false, false,
|
||||
+ 0xe.0000000000000008p-16388, false, false,
|
||||
+ 0xe.0000000000000008p-16388, false, false,
|
||||
+ 0xe.0000000000000008p-16388, false, false),
|
||||
+ TEST ("0x0.70000000000000000000000000002p-16382",
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x8p-152, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000008p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000004p-16384, false, true,
|
||||
+ false,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x0p+0, false, true,
|
||||
+ 0x4p-1076, false, true,
|
||||
+ false,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.cp-16384, false, true,
|
||||
+ 0x1.c000000000000000000000000004p-16384, false, true),
|
||||
};
|
598
glibc-RHEL-46739-4.patch
Normal file
598
glibc-RHEL-46739-4.patch
Normal file
@ -0,0 +1,598 @@
|
||||
commit 3fc063dee01da4f80920a14b7db637c8501d6fd4
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Tue Aug 27 20:41:54 2024 +0000
|
||||
|
||||
Make __strtod_internal tests type-generic
|
||||
|
||||
Some of the strtod tests use type-generic machinery in tst-strtod.h to
|
||||
test the strto* functions for all floating types, while others only
|
||||
test double even when the tests are in fact meaningful for all
|
||||
floating types.
|
||||
|
||||
Convert the tests of the internal __strtod_internal interface to cover
|
||||
all floating types. I haven't tried to convert them to use newer test
|
||||
interfaces in other ways, just made the changes necessary to use the
|
||||
type-generic machinery. As an internal interface, there are no
|
||||
aliases for different types with the same ABI (however,
|
||||
__strtold_internal is defined even if long double has the same ABI as
|
||||
double), so macros used by the type-generic testing code are redefined
|
||||
as needed to avoid expecting such aliases to be present.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
Conflicts:
|
||||
stdlib/tst-strtod4.c
|
||||
(69239bd7a216007692470aa9d5f3658024638742 missing downstream)
|
||||
|
||||
diff --git a/stdlib/tst-strtod1i.c b/stdlib/tst-strtod1i.c
|
||||
index 98fc5d527fe1edd9..32fc8b9e1f08ace9 100644
|
||||
--- a/stdlib/tst-strtod1i.c
|
||||
+++ b/stdlib/tst-strtod1i.c
|
||||
@@ -25,60 +25,91 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
-/* Perform a few tests in a locale with thousands separators. */
|
||||
-static int
|
||||
-do_test (void)
|
||||
-{
|
||||
- static const struct
|
||||
- {
|
||||
- const char *loc;
|
||||
- const char *str;
|
||||
- double exp;
|
||||
- ptrdiff_t nread;
|
||||
- } tests[] =
|
||||
- {
|
||||
- { "de_DE.UTF-8", "1,5", 1.5, 3 },
|
||||
- { "de_DE.UTF-8", "1.5", 1.0, 1 },
|
||||
- { "de_DE.UTF-8", "1.500", 1500.0, 5 },
|
||||
- { "de_DE.UTF-8", "36.893.488.147.419.103.232", 0x1.0p65, 26 }
|
||||
- };
|
||||
-#define ntests (sizeof (tests) / sizeof (tests[0]))
|
||||
- size_t n;
|
||||
- int result = 0;
|
||||
-
|
||||
- puts ("\nLocale tests");
|
||||
+#include "tst-strtod.h"
|
||||
|
||||
- for (n = 0; n < ntests; ++n)
|
||||
- {
|
||||
- double d;
|
||||
- char *endp;
|
||||
+/* This tests internal interfaces, which are only defined for types
|
||||
+ with distinct ABIs, so disable testing for types without distinct
|
||||
+ ABIs. */
|
||||
+#undef IF_FLOAT32
|
||||
+#define IF_FLOAT32(x)
|
||||
+#undef IF_FLOAT64
|
||||
+#define IF_FLOAT64(x)
|
||||
+#undef IF_FLOAT32X
|
||||
+#define IF_FLOAT32X(x)
|
||||
+#undef IF_FLOAT64X
|
||||
+#define IF_FLOAT64X(x)
|
||||
+#if !__HAVE_DISTINCT_FLOAT128
|
||||
+# undef IF_FLOAT128
|
||||
+# define IF_FLOAT128(x)
|
||||
+#endif
|
||||
|
||||
- if (setlocale (LC_ALL, tests[n].loc) == NULL)
|
||||
- {
|
||||
- printf ("cannot set locale %s\n", tests[n].loc);
|
||||
- result = 1;
|
||||
- continue;
|
||||
- }
|
||||
+#define ntests (sizeof (tests) / sizeof (tests[0]))
|
||||
|
||||
- d = __strtod_internal (tests[n].str, &endp, 1);
|
||||
- if (d != tests[n].exp)
|
||||
- {
|
||||
- printf ("strtod(\"%s\") returns %g and not %g\n",
|
||||
- tests[n].str, d, tests[n].exp);
|
||||
- result = 1;
|
||||
- }
|
||||
- else if (endp - tests[n].str != tests[n].nread)
|
||||
- {
|
||||
- printf ("strtod(\"%s\") read %td bytes and not %td\n",
|
||||
- tests[n].str, endp - tests[n].str, tests[n].nread);
|
||||
- result = 1;
|
||||
- }
|
||||
- }
|
||||
+/* Perform a few tests in a locale with thousands separators. */
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ static const struct \
|
||||
+ { \
|
||||
+ const char *loc; \
|
||||
+ const char *str; \
|
||||
+ FTYPE exp; \
|
||||
+ ptrdiff_t nread; \
|
||||
+ } tests[] = \
|
||||
+ { \
|
||||
+ { "de_DE.UTF-8", "1,5", 1.5 ## LSUF, 3 }, \
|
||||
+ { "de_DE.UTF-8", "1.5", 1.0 ## LSUF, 1 }, \
|
||||
+ { "de_DE.UTF-8", "1.500", 1500.0 ## LSUF, 5 }, \
|
||||
+ { "de_DE.UTF-8", "36.893.488.147.419.103.232", 0x1.0p65 ## LSUF, 26 } \
|
||||
+ }; \
|
||||
+ size_t n; \
|
||||
+ int result = 0; \
|
||||
+ \
|
||||
+ puts ("\nLocale tests"); \
|
||||
+ \
|
||||
+ for (n = 0; n < ntests; ++n) \
|
||||
+ { \
|
||||
+ FTYPE d; \
|
||||
+ char *endp; \
|
||||
+ \
|
||||
+ if (setlocale (LC_ALL, tests[n].loc) == NULL) \
|
||||
+ { \
|
||||
+ printf ("cannot set locale %s\n", tests[n].loc); \
|
||||
+ result = 1; \
|
||||
+ continue; \
|
||||
+ } \
|
||||
+ \
|
||||
+ d = __strto ## FSUF ## _internal (tests[n].str, &endp, 1); \
|
||||
+ if (d != tests[n].exp) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", d); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", tests[n].exp); \
|
||||
+ printf ("strto" # FSUF "(\"%s\") returns %s and not %s\n", \
|
||||
+ tests[n].str, buf1, buf2); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ else if (endp - tests[n].str != tests[n].nread) \
|
||||
+ { \
|
||||
+ printf ("strto" # FSUF "(\"%s\") read %td bytes and not %td\n", \
|
||||
+ tests[n].str, endp - tests[n].str, tests[n].nread); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (result == 0) \
|
||||
+ puts ("all OK"); \
|
||||
+ \
|
||||
+ return result ? EXIT_FAILURE : EXIT_SUCCESS; \
|
||||
+}
|
||||
|
||||
- if (result == 0)
|
||||
- puts ("all OK");
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
- return result ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
||||
diff --git a/stdlib/tst-strtod3.c b/stdlib/tst-strtod3.c
|
||||
index 23abec1896896276..0d662d8be83a7525 100644
|
||||
--- a/stdlib/tst-strtod3.c
|
||||
+++ b/stdlib/tst-strtod3.c
|
||||
@@ -3,19 +3,73 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
-static const struct
|
||||
-{
|
||||
- const char *in;
|
||||
- const char *out;
|
||||
- double expected;
|
||||
-} tests[] =
|
||||
- {
|
||||
- { "000,,,e1", ",,,e1", 0.0 },
|
||||
- { "000e1", "", 0.0 },
|
||||
- { "000,1e1", ",1e1", 0.0 }
|
||||
- };
|
||||
-#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+/* This tests internal interfaces, which are only defined for types
|
||||
+ with distinct ABIs, so disable testing for types without distinct
|
||||
+ ABIs. */
|
||||
+#undef IF_FLOAT32
|
||||
+#define IF_FLOAT32(x)
|
||||
+#undef IF_FLOAT64
|
||||
+#define IF_FLOAT64(x)
|
||||
+#undef IF_FLOAT32X
|
||||
+#define IF_FLOAT32X(x)
|
||||
+#undef IF_FLOAT64X
|
||||
+#define IF_FLOAT64X(x)
|
||||
+#if !__HAVE_DISTINCT_FLOAT128
|
||||
+# undef IF_FLOAT128
|
||||
+# define IF_FLOAT128(x)
|
||||
+#endif
|
||||
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static const struct \
|
||||
+{ \
|
||||
+ const char *in; \
|
||||
+ const char *out; \
|
||||
+ FTYPE expected; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+ { \
|
||||
+ { "000,,,e1", ",,,e1", 0.0 ## LSUF }, \
|
||||
+ { "000e1", "", 0.0 ## LSUF }, \
|
||||
+ { "000,1e1", ",1e1", 0.0 ## LSUF } \
|
||||
+ }; \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ \
|
||||
+ for (int i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \
|
||||
+ &ep, 1); \
|
||||
+ \
|
||||
+ if (strcmp (ep, tests_strto ## FSUF[i].out) != 0) \
|
||||
+ { \
|
||||
+ printf ("%d: got rest string \"%s\", expected \"%s\"\n", \
|
||||
+ i, ep, tests_strto ## FSUF[i].out); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (r != tests_strto ## FSUF[i].expected) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", \
|
||||
+ tests_strto ## FSUF[i].expected); \
|
||||
+ printf ("%d: got wrong results %s, expected %s\n", \
|
||||
+ i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ return status; \
|
||||
+}
|
||||
+
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -26,29 +80,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- int status = 0;
|
||||
-
|
||||
- for (int i = 0; i < NTESTS; ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = __strtod_internal (tests[i].in, &ep, 1);
|
||||
-
|
||||
- if (strcmp (ep, tests[i].out) != 0)
|
||||
- {
|
||||
- printf ("%d: got rest string \"%s\", expected \"%s\"\n",
|
||||
- i, ep, tests[i].out);
|
||||
- status = 1;
|
||||
- }
|
||||
-
|
||||
- if (r != tests[i].expected)
|
||||
- {
|
||||
- printf ("%d: got wrong results %g, expected %g\n",
|
||||
- i, r, tests[i].expected);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
diff --git a/stdlib/tst-strtod4.c b/stdlib/tst-strtod4.c
|
||||
index aae9835d82d38b4e..cd86f8c1f13a39e4 100644
|
||||
--- a/stdlib/tst-strtod4.c
|
||||
+++ b/stdlib/tst-strtod4.c
|
||||
@@ -3,20 +3,74 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+/* This tests internal interfaces, which are only defined for types
|
||||
+ with distinct ABIs, so disable testing for types without distinct
|
||||
+ ABIs. */
|
||||
+#undef IF_FLOAT32
|
||||
+#define IF_FLOAT32(x)
|
||||
+#undef IF_FLOAT64
|
||||
+#define IF_FLOAT64(x)
|
||||
+#undef IF_FLOAT32X
|
||||
+#define IF_FLOAT32X(x)
|
||||
+#undef IF_FLOAT64X
|
||||
+#define IF_FLOAT64X(x)
|
||||
+#if !__HAVE_DISTINCT_FLOAT128
|
||||
+# undef IF_FLOAT128
|
||||
+# define IF_FLOAT128(x)
|
||||
+#endif
|
||||
+
|
||||
#define NNBSP "\xe2\x80\xaf"
|
||||
|
||||
-static const struct
|
||||
-{
|
||||
- const char *in;
|
||||
- const char *out;
|
||||
- double expected;
|
||||
-} tests[] =
|
||||
- {
|
||||
- { "000"NNBSP"000"NNBSP"000", "", 0.0 },
|
||||
- { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 }
|
||||
- };
|
||||
-#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static const struct \
|
||||
+{ \
|
||||
+ const char *in; \
|
||||
+ const char *out; \
|
||||
+ FTYPE expected; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+ { \
|
||||
+ { "000"NNBSP"000"NNBSP"000", "", 0.0 ## LSUF }, \
|
||||
+ { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 ## LSUF } \
|
||||
+ }; \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ \
|
||||
+ for (int i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \
|
||||
+ &ep, 1); \
|
||||
+ \
|
||||
+ if (strcmp (ep, tests_strto ## FSUF[i].out) != 0) \
|
||||
+ { \
|
||||
+ printf ("%d: got rest string \"%s\", expected \"%s\"\n", \
|
||||
+ i, ep, tests_strto ## FSUF[i].out); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (r != tests_strto ## FSUF[i].expected) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", \
|
||||
+ tests_strto ## FSUF[i].expected); \
|
||||
+ printf ("%d: got wrong results %s, expected %s\n", \
|
||||
+ i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ return status; \
|
||||
+}
|
||||
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -27,29 +81,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- int status = 0;
|
||||
-
|
||||
- for (int i = 0; i < NTESTS; ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = __strtod_internal (tests[i].in, &ep, 1);
|
||||
-
|
||||
- if (strcmp (ep, tests[i].out) != 0)
|
||||
- {
|
||||
- printf ("%d: got rest string \"%s\", expected \"%s\"\n",
|
||||
- i, ep, tests[i].out);
|
||||
- status = 1;
|
||||
- }
|
||||
-
|
||||
- if (r != tests[i].expected)
|
||||
- {
|
||||
- printf ("%d: got wrong results %g, expected %g\n",
|
||||
- i, r, tests[i].expected);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
diff --git a/stdlib/tst-strtod5i.c b/stdlib/tst-strtod5i.c
|
||||
index ba3e78d5f2933586..0ddae2b94765de39 100644
|
||||
--- a/stdlib/tst-strtod5i.c
|
||||
+++ b/stdlib/tst-strtod5i.c
|
||||
@@ -16,52 +16,112 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* Defining _LIBC_TEST ensures long double math functions are
|
||||
+ declared in the headers. */
|
||||
+#define _LIBC_TEST 1
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+/* This tests internal interfaces, which are only defined for types
|
||||
+ with distinct ABIs, so disable testing for types without distinct
|
||||
+ ABIs. */
|
||||
+#undef IF_FLOAT32
|
||||
+#define IF_FLOAT32(x)
|
||||
+#undef IF_FLOAT64
|
||||
+#define IF_FLOAT64(x)
|
||||
+#undef IF_FLOAT32X
|
||||
+#define IF_FLOAT32X(x)
|
||||
+#undef IF_FLOAT64X
|
||||
+#define IF_FLOAT64X(x)
|
||||
+#if !__HAVE_DISTINCT_FLOAT128
|
||||
+# undef IF_FLOAT128
|
||||
+# define IF_FLOAT128(x)
|
||||
+#endif
|
||||
+
|
||||
#define NNBSP "\xe2\x80\xaf"
|
||||
|
||||
-static const struct
|
||||
-{
|
||||
- const char *in;
|
||||
- int group;
|
||||
- double expected;
|
||||
-} tests[] =
|
||||
- {
|
||||
- { "0", 0, 0.0 },
|
||||
- { "000", 0, 0.0 },
|
||||
- { "-0", 0, -0.0 },
|
||||
- { "-000", 0, -0.0 },
|
||||
- { "0,", 0, 0.0 },
|
||||
- { "-0,", 0, -0.0 },
|
||||
- { "0,0", 0, 0.0 },
|
||||
- { "-0,0", 0, -0.0 },
|
||||
- { "0e-10", 0, 0.0 },
|
||||
- { "-0e-10", 0, -0.0 },
|
||||
- { "0,e-10", 0, 0.0 },
|
||||
- { "-0,e-10", 0, -0.0 },
|
||||
- { "0,0e-10", 0, 0.0 },
|
||||
- { "-0,0e-10", 0, -0.0 },
|
||||
- { "0e-1000000", 0, 0.0 },
|
||||
- { "-0e-1000000", 0, -0.0 },
|
||||
- { "0,0e-1000000", 0, 0.0 },
|
||||
- { "-0,0e-1000000", 0, -0.0 },
|
||||
- { "0", 1, 0.0 },
|
||||
- { "000", 1, 0.0 },
|
||||
- { "-0", 1, -0.0 },
|
||||
- { "-000", 1, -0.0 },
|
||||
- { "0e-10", 1, 0.0 },
|
||||
- { "-0e-10", 1, -0.0 },
|
||||
- { "0e-1000000", 1, 0.0 },
|
||||
- { "-0e-1000000", 1, -0.0 },
|
||||
- { "000"NNBSP"000"NNBSP"000", 1, 0.0 },
|
||||
- { "-000"NNBSP"000"NNBSP"000", 1, -0.0 }
|
||||
- };
|
||||
-#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static const struct \
|
||||
+{ \
|
||||
+ const char *in; \
|
||||
+ int group; \
|
||||
+ FTYPE expected; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+ { \
|
||||
+ { "0", 0, 0.0 ## LSUF }, \
|
||||
+ { "000", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0", 0, -0.0 ## LSUF }, \
|
||||
+ { "-000", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,0", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,0", 0, -0.0 ## LSUF }, \
|
||||
+ { "0e-10", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0e-10", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,e-10", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,e-10", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,0e-10", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,0e-10", 0, -0.0 ## LSUF }, \
|
||||
+ { "0e-1000000", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0e-1000000", 0, -0.0 ## LSUF }, \
|
||||
+ { "0,0e-1000000", 0, 0.0 ## LSUF }, \
|
||||
+ { "-0,0e-1000000", 0, -0.0 ## LSUF }, \
|
||||
+ { "0", 1, 0.0 ## LSUF }, \
|
||||
+ { "000", 1, 0.0 ## LSUF }, \
|
||||
+ { "-0", 1, -0.0 ## LSUF }, \
|
||||
+ { "-000", 1, -0.0 ## LSUF }, \
|
||||
+ { "0e-10", 1, 0.0 ## LSUF }, \
|
||||
+ { "-0e-10", 1, -0.0 ## LSUF }, \
|
||||
+ { "0e-1000000", 1, 0.0 ## LSUF }, \
|
||||
+ { "-0e-1000000", 1, -0.0 ## LSUF }, \
|
||||
+ { "000"NNBSP"000"NNBSP"000", 1, 0.0 ## LSUF }, \
|
||||
+ { "-000"NNBSP"000"NNBSP"000", 1, -0.0 ## LSUF } \
|
||||
+ }; \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ \
|
||||
+ for (int i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \
|
||||
+ &ep, \
|
||||
+ tests_strto ## FSUF[i].group); \
|
||||
+ \
|
||||
+ if (*ep != '\0') \
|
||||
+ { \
|
||||
+ printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (r != tests_strto ## FSUF[i].expected \
|
||||
+ || (copysign ## CSUF (10.0 ## LSUF, r) \
|
||||
+ != copysign ## CSUF (10.0 ## LSUF, \
|
||||
+ tests_strto ## FSUF[i].expected))) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", \
|
||||
+ tests_strto ## FSUF[i].expected); \
|
||||
+ printf ("%d: got wrong results %s, expected %s\n", \
|
||||
+ i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ return status; \
|
||||
+}
|
||||
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -72,29 +132,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- int status = 0;
|
||||
-
|
||||
- for (int i = 0; i < NTESTS; ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = __strtod_internal (tests[i].in, &ep, tests[i].group);
|
||||
-
|
||||
- if (*ep != '\0')
|
||||
- {
|
||||
- printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep);
|
||||
- status = 1;
|
||||
- }
|
||||
-
|
||||
- if (r != tests[i].expected
|
||||
- || copysign (10.0, r) != copysign (10.0, tests[i].expected))
|
||||
- {
|
||||
- printf ("%d: got wrong results %g, expected %g\n",
|
||||
- i, r, tests[i].expected);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
140
glibc-RHEL-46739-5.patch
Normal file
140
glibc-RHEL-46739-5.patch
Normal file
@ -0,0 +1,140 @@
|
||||
commit be77d5ae417236883c02d3d67c0716e3f669fa41
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Wed Sep 4 13:20:18 2024 +0000
|
||||
|
||||
Improve NaN payload testing
|
||||
|
||||
There are two separate sets of tests of NaN payloads in glibc:
|
||||
|
||||
* libm-test-{get,set}payload* verify that getpayload, setpayload,
|
||||
setpayloadsig and __builtin_nan functions are consistent in their
|
||||
payload handling.
|
||||
|
||||
* test-nan-payload verifies that strtod-family functions and the
|
||||
not-built-in nan functions are consistent in their payload handling.
|
||||
|
||||
Nothing, however, connects the two sets of functions (i.e., verifies
|
||||
that strtod / nan are consistent with getpayload / setpayload /
|
||||
__builtin_nan).
|
||||
|
||||
Improve test-nan-payload to check actual payload value with getpayload
|
||||
rather than just verifying that the strtod and nan functions produce
|
||||
the same NaN. Also check that the NaNs produced aren't signaling and
|
||||
extend the tests to cover _FloatN / _FloatNx.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/math/test-nan-payload.c b/math/test-nan-payload.c
|
||||
index 88fd727e63b2fda2..0ee5432d40a3f997 100644
|
||||
--- a/math/test-nan-payload.c
|
||||
+++ b/math/test-nan-payload.c
|
||||
@@ -16,6 +16,8 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#define _LIBC_TEST 1
|
||||
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
@@ -31,7 +33,7 @@
|
||||
#define CHECK_IS_NAN(TYPE, A) \
|
||||
do \
|
||||
{ \
|
||||
- if (isnan (A)) \
|
||||
+ if (isnan (A) && !issignaling (A)) \
|
||||
puts ("PASS: " #TYPE " " #A); \
|
||||
else \
|
||||
{ \
|
||||
@@ -41,6 +43,19 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
+#define CHECK_PAYLOAD(TYPE, FUNC, A, P) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ if (FUNC (&(A)) == (P)) \
|
||||
+ puts ("PASS: " #TYPE " payload " #A); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ puts ("FAIL: " #TYPE " payload " #A); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
#define CHECK_SAME_NAN(TYPE, A, B) \
|
||||
do \
|
||||
{ \
|
||||
@@ -71,7 +86,7 @@
|
||||
bits. */
|
||||
#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
|
||||
|
||||
-#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG) \
|
||||
+#define RUN_TESTS(TYPE, SFUNC, FUNC, PLFUNC, MANT_DIG) \
|
||||
do \
|
||||
{ \
|
||||
TYPE n123 = WRAP_NAN (FUNC, "123"); \
|
||||
@@ -82,6 +97,10 @@
|
||||
CHECK_IS_NAN (TYPE, n456); \
|
||||
TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \
|
||||
CHECK_IS_NAN (TYPE, s456); \
|
||||
+ TYPE nh123 = WRAP_NAN (FUNC, "0x123"); \
|
||||
+ CHECK_IS_NAN (TYPE, nh123); \
|
||||
+ TYPE sh123 = WRAP_STRTO (SFUNC, "NAN(0x123)"); \
|
||||
+ CHECK_IS_NAN (TYPE, sh123); \
|
||||
TYPE n123x = WRAP_NAN (FUNC, "123)"); \
|
||||
CHECK_IS_NAN (TYPE, n123x); \
|
||||
TYPE nemp = WRAP_NAN (FUNC, ""); \
|
||||
@@ -92,8 +111,16 @@
|
||||
CHECK_IS_NAN (TYPE, sx); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
CHECK_SAME_NAN (TYPE, n123, s123); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, n123, 123); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, s123, 123); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
CHECK_SAME_NAN (TYPE, n456, s456); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, n456, 456); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, s456, 456); \
|
||||
+ if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
+ CHECK_SAME_NAN (TYPE, nh123, sh123); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, nh123, 0x123); \
|
||||
+ CHECK_PAYLOAD (TYPE, PLFUNC, sh123, 0x123); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
CHECK_SAME_NAN (TYPE, nemp, semp); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
@@ -110,9 +137,31 @@ static int
|
||||
do_test (void)
|
||||
{
|
||||
int result = 0;
|
||||
- RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG);
|
||||
- RUN_TESTS (double, strtod, nan, DBL_MANT_DIG);
|
||||
- RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG);
|
||||
+ RUN_TESTS (float, strtof, nanf, getpayloadf, FLT_MANT_DIG);
|
||||
+ RUN_TESTS (double, strtod, nan, getpayload, DBL_MANT_DIG);
|
||||
+ RUN_TESTS (long double, strtold, nanl, getpayloadl, LDBL_MANT_DIG);
|
||||
+#if __HAVE_FLOAT16
|
||||
+ RUN_TESTS (_Float16, strtof16, nanf16, getpayloadf16, FLT16_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT32
|
||||
+ RUN_TESTS (_Float32, strtof32, nanf32, getpayloadf32, FLT32_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT64
|
||||
+ RUN_TESTS (_Float64, strtof64, nanf64, getpayloadf64, FLT64_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT128
|
||||
+ RUN_TESTS (_Float128, strtof128, nanf128, getpayloadf128, FLT128_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT32X
|
||||
+ RUN_TESTS (_Float32x, strtof32x, nanf32x, getpayloadf32x, FLT32X_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT64X
|
||||
+ RUN_TESTS (_Float64x, strtof64x, nanf64x, getpayloadf64x, FLT64X_MANT_DIG);
|
||||
+#endif
|
||||
+#if __HAVE_FLOAT128X
|
||||
+ RUN_TESTS (_Float128x, strtof128x, nanf128x, getpayloadf128x,
|
||||
+ FLT128X_MANT_DIG);
|
||||
+#endif
|
||||
return result;
|
||||
}
|
||||
|
147
glibc-RHEL-46739-6.patch
Normal file
147
glibc-RHEL-46739-6.patch
Normal file
@ -0,0 +1,147 @@
|
||||
commit 64f62c47e9c350f353336f2df6714e1d48ec50d8
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Wed Sep 4 13:21:23 2024 +0000
|
||||
|
||||
Do not set errno for overflowing NaN payload in strtod/nan (bug 32045)
|
||||
|
||||
As reported in bug 32045, it's incorrect for strtod/nan functions to
|
||||
set errno based on overflowing payload (strtod should only set errno
|
||||
for overflow / underflow of its actual result, and potentially if
|
||||
nothing in the string can be parsed as a number at all; nan should be
|
||||
a pure function that never sets it). Save and restore errno around
|
||||
the internal strtoull call and add associated test coverage.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/math/Makefile b/math/Makefile
|
||||
index 2edb044d9d590de1..a3c44def8acae93b 100644
|
||||
--- a/math/Makefile
|
||||
+++ b/math/Makefile
|
||||
@@ -452,6 +452,7 @@ CFLAGS-test-flt-eval-method.c += -fexcess-precision=standard
|
||||
CFLAGS-test-fe-snans-always-signal.c += -fsignaling-nans
|
||||
|
||||
CFLAGS-test-nan-const.c += -fno-builtin
|
||||
+CFLAGS-test-nan-payload.c += -fno-builtin
|
||||
|
||||
include ../Rules
|
||||
|
||||
diff --git a/math/test-nan-payload.c b/math/test-nan-payload.c
|
||||
index 0ee5432d40a3f997..5f54bf26b6163816 100644
|
||||
--- a/math/test-nan-payload.c
|
||||
+++ b/math/test-nan-payload.c
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#define _LIBC_TEST 1
|
||||
#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
+#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
@@ -82,6 +83,26 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
+#define CLEAR_ERRNO \
|
||||
+ do \
|
||||
+ { \
|
||||
+ errno = 12345; \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+#define CHECK_ERRNO(TYPE, A) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ if (errno == 12345) \
|
||||
+ puts ("PASS: " #TYPE " " #A " errno"); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ puts ("FAIL: " #TYPE " " #A " errno"); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
/* Cannot test payloads by memcmp for formats where NaNs have padding
|
||||
bits. */
|
||||
#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
|
||||
@@ -89,26 +110,58 @@
|
||||
#define RUN_TESTS(TYPE, SFUNC, FUNC, PLFUNC, MANT_DIG) \
|
||||
do \
|
||||
{ \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE n123 = WRAP_NAN (FUNC, "123"); \
|
||||
+ CHECK_ERRNO (TYPE, n123); \
|
||||
CHECK_IS_NAN (TYPE, n123); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)"); \
|
||||
+ CHECK_ERRNO (TYPE, s123); \
|
||||
CHECK_IS_NAN (TYPE, s123); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE n456 = WRAP_NAN (FUNC, "456"); \
|
||||
+ CHECK_ERRNO (TYPE, n456); \
|
||||
CHECK_IS_NAN (TYPE, n456); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \
|
||||
+ CHECK_ERRNO (TYPE, s456); \
|
||||
CHECK_IS_NAN (TYPE, s456); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE nh123 = WRAP_NAN (FUNC, "0x123"); \
|
||||
+ CHECK_ERRNO (TYPE, nh123); \
|
||||
CHECK_IS_NAN (TYPE, nh123); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE sh123 = WRAP_STRTO (SFUNC, "NAN(0x123)"); \
|
||||
+ CHECK_ERRNO (TYPE, sh123); \
|
||||
CHECK_IS_NAN (TYPE, sh123); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE n123x = WRAP_NAN (FUNC, "123)"); \
|
||||
+ CHECK_ERRNO (TYPE, n123x); \
|
||||
CHECK_IS_NAN (TYPE, n123x); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE nemp = WRAP_NAN (FUNC, ""); \
|
||||
+ CHECK_ERRNO (TYPE, nemp); \
|
||||
CHECK_IS_NAN (TYPE, nemp); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE semp = WRAP_STRTO (SFUNC, "NAN()"); \
|
||||
+ CHECK_ERRNO (TYPE, semp); \
|
||||
CHECK_IS_NAN (TYPE, semp); \
|
||||
+ CLEAR_ERRNO; \
|
||||
TYPE sx = WRAP_STRTO (SFUNC, "NAN"); \
|
||||
+ CHECK_ERRNO (TYPE, sx); \
|
||||
CHECK_IS_NAN (TYPE, sx); \
|
||||
+ CLEAR_ERRNO; \
|
||||
+ TYPE novf = WRAP_NAN (FUNC, "9999999999" \
|
||||
+ "99999999999999999999" \
|
||||
+ "9999999999"); \
|
||||
+ CHECK_ERRNO (TYPE, novf); \
|
||||
+ CHECK_IS_NAN (TYPE, novf); \
|
||||
+ CLEAR_ERRNO; \
|
||||
+ TYPE sovf = WRAP_STRTO (SFUNC, "NAN(9999999999" \
|
||||
+ "99999999999999999999" \
|
||||
+ "9999999999)"); \
|
||||
+ CHECK_ERRNO (TYPE, sovf); \
|
||||
+ CHECK_IS_NAN (TYPE, sovf); \
|
||||
if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
CHECK_SAME_NAN (TYPE, n123, s123); \
|
||||
CHECK_PAYLOAD (TYPE, PLFUNC, n123, 123); \
|
||||
diff --git a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c
|
||||
index ba81355d1c0dbeda..8d7d43818bdba79a 100644
|
||||
--- a/stdlib/strtod_nan_main.c
|
||||
+++ b/stdlib/strtod_nan_main.c
|
||||
@@ -16,6 +16,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <errno.h>
|
||||
#include <ieee754.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
@@ -50,7 +51,9 @@ STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc)
|
||||
STRING_TYPE *endp;
|
||||
unsigned long long int mant;
|
||||
|
||||
+ int save_errno = errno;
|
||||
mant = STRTOULL (str, &endp, 0);
|
||||
+ __set_errno (save_errno);
|
||||
if (endp == cp)
|
||||
SET_NAN_PAYLOAD (retval, mant);
|
||||
|
76
glibc-RHEL-46739-7.patch
Normal file
76
glibc-RHEL-46739-7.patch
Normal file
@ -0,0 +1,76 @@
|
||||
commit cc3e743fc09ee6fca45767629df9cbcbe1feba82
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Sep 5 21:18:23 2024 +0200
|
||||
|
||||
powerpc64le: Build new strtod tests with long double ABI flags (bug 32145)
|
||||
|
||||
This fixes several test failures:
|
||||
|
||||
=====FAIL: stdlib/tst-strtod1i.out=====
|
||||
Locale tests
|
||||
all OK
|
||||
Locale tests
|
||||
all OK
|
||||
Locale tests
|
||||
strtold("1,5") returns -6,38643e+367 and not 1,5
|
||||
strtold("1.5") returns 1,5 and not 1
|
||||
strtold("1.500") returns 1 and not 1500
|
||||
strtold("36.893.488.147.419.103.232") returns 1500 and not 3,68935e+19
|
||||
Locale tests
|
||||
all OK
|
||||
|
||||
=====FAIL: stdlib/tst-strtod3.out=====
|
||||
0: got wrong results -2.5937e+4826, expected 0
|
||||
|
||||
=====FAIL: stdlib/tst-strtod4.out=====
|
||||
0: got wrong results -6,38643e+367, expected 0
|
||||
1: got wrong results 0, expected 1e+06
|
||||
2: got wrong results 1e+06, expected 10
|
||||
|
||||
=====FAIL: stdlib/tst-strtod5i.out=====
|
||||
0: got wrong results -6,38643e+367, expected 0
|
||||
2: got wrong results 0, expected -0
|
||||
4: got wrong results -0, expected 0
|
||||
5: got wrong results 0, expected -0
|
||||
6: got wrong results -0, expected 0
|
||||
7: got wrong results 0, expected -0
|
||||
8: got wrong results -0, expected 0
|
||||
9: got wrong results 0, expected -0
|
||||
10: got wrong results -0, expected 0
|
||||
11: got wrong results 0, expected -0
|
||||
12: got wrong results -0, expected 0
|
||||
13: got wrong results 0, expected -0
|
||||
14: got wrong results -0, expected 0
|
||||
15: got wrong results 0, expected -0
|
||||
16: got wrong results -0, expected 0
|
||||
17: got wrong results 0, expected -0
|
||||
18: got wrong results -0, expected 0
|
||||
20: got wrong results 0, expected -0
|
||||
22: got wrong results -0, expected 0
|
||||
23: got wrong results 0, expected -0
|
||||
24: got wrong results -0, expected 0
|
||||
25: got wrong results 0, expected -0
|
||||
26: got wrong results -0, expected 0
|
||||
27: got wrong results 0, expected -0
|
||||
|
||||
Fixes commit 3fc063dee01da4f80920a14b7db637c8501d6fd4
|
||||
("Make __strtod_internal tests type-generic").
|
||||
|
||||
Suggested-by: Joseph Myers <josmyers@redhat.com>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc64/le/Makefile b/sysdeps/powerpc/powerpc64/le/Makefile
|
||||
index 7c036b45fcc0d7f9..8bc71fd18d3f1edc 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/le/Makefile
|
||||
+++ b/sysdeps/powerpc/powerpc64/le/Makefile
|
||||
@@ -128,6 +128,10 @@ CFLAGS-tst-strtod-round.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-wcstod-round.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-strtod-nan-locale.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-wcstod-nan-locale.c += $(type-float128-CFLAGS)
|
||||
+CFLAGS-tst-strtod1i.c += $(type-float128-CFLAGS)
|
||||
+CFLAGS-tst-strtod3.c += $(type-float128-CFLAGS)
|
||||
+CFLAGS-tst-strtod4.c += $(type-float128-CFLAGS)
|
||||
+CFLAGS-tst-strtod5i.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-strtod6.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-strfrom.c += $(type-float128-CFLAGS)
|
||||
CFLAGS-tst-strfrom-locale.c += $(type-float128-CFLAGS)
|
254
glibc-RHEL-46739-8.patch
Normal file
254
glibc-RHEL-46739-8.patch
Normal file
@ -0,0 +1,254 @@
|
||||
commit 8de031bcb9adfa736c0caed2c79d10947b8d8f48
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:23:13 2024 +0000
|
||||
|
||||
Make tst-strtod2 and tst-strtod5 type-generic
|
||||
|
||||
Some of the strtod tests use type-generic machinery in tst-strtod.h to
|
||||
test the strto* functions for all floating types, while others only
|
||||
test double even when the tests are in fact meaningful for all
|
||||
floating types.
|
||||
|
||||
Convert tst-strtod2 and tst-strtod5 to use the type-generic machinery
|
||||
so they test all floating types. I haven't tried to convert them to
|
||||
use newer test interfaces in other ways, just made the changes
|
||||
necessary to use the type-generic machinery.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c
|
||||
index a7df82ebbde14c5f..2cb0953fa911efd0 100644
|
||||
--- a/stdlib/tst-strtod2.c
|
||||
+++ b/stdlib/tst-strtod2.c
|
||||
@@ -1,43 +1,61 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
-struct test
|
||||
-{
|
||||
- const char *str;
|
||||
- double result;
|
||||
- size_t offset;
|
||||
-} tests[] =
|
||||
-{
|
||||
- { "0xy", 0.0, 1 },
|
||||
- { "0x.y", 0.0, 1 },
|
||||
- { "0x0.y", 0.0, 4 },
|
||||
- { "0x.0y", 0.0, 4 },
|
||||
- { ".y", 0.0, 0 },
|
||||
- { "0.y", 0.0, 2 },
|
||||
- { ".0y", 0.0, 2 }
|
||||
-};
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+struct test_strto ## FSUF \
|
||||
+{ \
|
||||
+ const char *str; \
|
||||
+ FTYPE result; \
|
||||
+ size_t offset; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+{ \
|
||||
+ { "0xy", 0.0 ## LSUF, 1 }, \
|
||||
+ { "0x.y", 0.0 ## LSUF, 1 }, \
|
||||
+ { "0x0.y", 0.0 ## LSUF, 4 }, \
|
||||
+ { "0x.0y", 0.0 ## LSUF, 4 }, \
|
||||
+ { ".y", 0.0 ## LSUF, 0 }, \
|
||||
+ { "0.y", 0.0 ## LSUF, 2 }, \
|
||||
+ { ".0y", 0.0 ## LSUF, 2 } \
|
||||
+}; \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ for (size_t i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].str, &ep); \
|
||||
+ if (r != tests_strto ## FSUF[i].result) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", tests_strto ## FSUF[i].result); \
|
||||
+ printf ("test %zu r = %s, expect %s\n", i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ if (ep != tests_strto ## FSUF[i].str + tests_strto ## FSUF[i].offset) \
|
||||
+ { \
|
||||
+ printf ("test %zu strto" #FSUF \
|
||||
+ " parsed %tu characters, expected %zu\n", \
|
||||
+ i, ep - tests_strto ## FSUF[i].str, \
|
||||
+ tests_strto ## FSUF[i].offset); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ return status; \
|
||||
+}
|
||||
+
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- int status = 0;
|
||||
- for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = strtod (tests[i].str, &ep);
|
||||
- if (r != tests[i].result)
|
||||
- {
|
||||
- printf ("test %zu r = %g, expect %g\n", i, r, tests[i].result);
|
||||
- status = 1;
|
||||
- }
|
||||
- if (ep != tests[i].str + tests[i].offset)
|
||||
- {
|
||||
- printf ("test %zu strtod parsed %tu characters, expected %zu\n",
|
||||
- i, ep - tests[i].str, tests[i].offset);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
diff --git a/stdlib/tst-strtod5.c b/stdlib/tst-strtod5.c
|
||||
index be091ec1b9f87394..005b3480a76955da 100644
|
||||
--- a/stdlib/tst-strtod5.c
|
||||
+++ b/stdlib/tst-strtod5.c
|
||||
@@ -22,35 +22,75 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
+#include "tst-strtod.h"
|
||||
+
|
||||
#define NBSP "\xc2\xa0"
|
||||
|
||||
-static const struct
|
||||
-{
|
||||
- const char *in;
|
||||
- double expected;
|
||||
-} tests[] =
|
||||
- {
|
||||
- { "0", 0.0 },
|
||||
- { "000", 0.0 },
|
||||
- { "-0", -0.0 },
|
||||
- { "-000", -0.0 },
|
||||
- { "0,", 0.0 },
|
||||
- { "-0,", -0.0 },
|
||||
- { "0,0", 0.0 },
|
||||
- { "-0,0", -0.0 },
|
||||
- { "0e-10", 0.0 },
|
||||
- { "-0e-10", -0.0 },
|
||||
- { "0,e-10", 0.0 },
|
||||
- { "-0,e-10", -0.0 },
|
||||
- { "0,0e-10", 0.0 },
|
||||
- { "-0,0e-10", -0.0 },
|
||||
- { "0e-1000000", 0.0 },
|
||||
- { "-0e-1000000", -0.0 },
|
||||
- { "0,0e-1000000", 0.0 },
|
||||
- { "-0,0e-1000000", -0.0 },
|
||||
- };
|
||||
-#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
+static const struct \
|
||||
+{ \
|
||||
+ const char *in; \
|
||||
+ FTYPE expected; \
|
||||
+} tests_strto ## FSUF[] = \
|
||||
+ { \
|
||||
+ { "0", 0.0 ## LSUF }, \
|
||||
+ { "000", 0.0 ## LSUF }, \
|
||||
+ { "-0", -0.0 ## LSUF }, \
|
||||
+ { "-000", -0.0 ## LSUF }, \
|
||||
+ { "0,", 0.0 ## LSUF }, \
|
||||
+ { "-0,", -0.0 ## LSUF }, \
|
||||
+ { "0,0", 0.0 ## LSUF }, \
|
||||
+ { "-0,0", -0.0 ## LSUF }, \
|
||||
+ { "0e-10", 0.0 ## LSUF }, \
|
||||
+ { "-0e-10", -0.0 ## LSUF }, \
|
||||
+ { "0,e-10", 0.0 ## LSUF }, \
|
||||
+ { "-0,e-10", -0.0 ## LSUF }, \
|
||||
+ { "0,0e-10", 0.0 ## LSUF }, \
|
||||
+ { "-0,0e-10", -0.0 ## LSUF }, \
|
||||
+ { "0e-1000000", 0.0 ## LSUF }, \
|
||||
+ { "-0e-1000000", -0.0 ## LSUF }, \
|
||||
+ { "0,0e-1000000", 0.0 ## LSUF }, \
|
||||
+ { "-0,0e-1000000", -0.0 ## LSUF }, \
|
||||
+ }; \
|
||||
+ \
|
||||
+ \
|
||||
+static int \
|
||||
+test_strto ## FSUF (void) \
|
||||
+{ \
|
||||
+ int status = 0; \
|
||||
+ \
|
||||
+ for (int i = 0; \
|
||||
+ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \
|
||||
+ ++i) \
|
||||
+ { \
|
||||
+ char *ep; \
|
||||
+ FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].in, &ep); \
|
||||
+ \
|
||||
+ if (*ep != '\0') \
|
||||
+ { \
|
||||
+ printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ \
|
||||
+ if (r != tests_strto ## FSUF[i].expected \
|
||||
+ || (copysign ## CSUF (10.0 ## LSUF, r) \
|
||||
+ != copysign ## CSUF (10.0 ## LSUF, \
|
||||
+ tests_strto ## FSUF[i].expected))) \
|
||||
+ { \
|
||||
+ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
+ FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
||||
+ FTOSTR (buf2, sizeof (buf2), "%g", \
|
||||
+ tests_strto ## FSUF[i].expected); \
|
||||
+ printf ("%d: got wrong results %s, expected %s\n", \
|
||||
+ i, buf1, buf2); \
|
||||
+ status = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ \
|
||||
+ return status; \
|
||||
+}
|
||||
|
||||
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -61,29 +101,7 @@ do_test (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- int status = 0;
|
||||
-
|
||||
- for (int i = 0; i < NTESTS; ++i)
|
||||
- {
|
||||
- char *ep;
|
||||
- double r = strtod (tests[i].in, &ep);
|
||||
-
|
||||
- if (*ep != '\0')
|
||||
- {
|
||||
- printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep);
|
||||
- status = 1;
|
||||
- }
|
||||
-
|
||||
- if (r != tests[i].expected
|
||||
- || copysign (10.0, r) != copysign (10.0, tests[i].expected))
|
||||
- {
|
||||
- printf ("%d: got wrong results %g, expected %g\n",
|
||||
- i, r, tests[i].expected);
|
||||
- status = 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return status;
|
||||
+ return STRTOD_TEST_FOREACH (test_strto);
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
79
glibc-RHEL-46739-9.patch
Normal file
79
glibc-RHEL-46739-9.patch
Normal file
@ -0,0 +1,79 @@
|
||||
commit b5d3737b305525315e0c7c93ca49eadc868eabd5
|
||||
Author: Joseph Myers <josmyers@redhat.com>
|
||||
Date: Fri Sep 20 23:24:02 2024 +0000
|
||||
|
||||
Add more tests of strtod end pointer
|
||||
|
||||
Although there are some tests in tst-strtod2 and tst-strtod3 for the
|
||||
end pointer provided by strtod when it doesn't parse the whole string,
|
||||
they aren't very thorough. Add tests of more such cases to
|
||||
tst-strtod2.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c
|
||||
index 2cb0953fa911efd0..c84bd792c1a3f511 100644
|
||||
--- a/stdlib/tst-strtod2.c
|
||||
+++ b/stdlib/tst-strtod2.c
|
||||
@@ -1,3 +1,4 @@
|
||||
+#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -17,10 +18,46 @@ struct test_strto ## FSUF \
|
||||
{ "0x.0y", 0.0 ## LSUF, 4 }, \
|
||||
{ ".y", 0.0 ## LSUF, 0 }, \
|
||||
{ "0.y", 0.0 ## LSUF, 2 }, \
|
||||
- { ".0y", 0.0 ## LSUF, 2 } \
|
||||
+ { ".0y", 0.0 ## LSUF, 2 }, \
|
||||
+ { "1.0e", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0e+", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0e-", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0ex", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0e+x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "1.0e-x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p+", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p-", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1px", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p+x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "0x1p-x", 1.0 ## LSUF, 3 }, \
|
||||
+ { "INFx", INFINITY, 3 }, \
|
||||
+ { "infx", INFINITY, 3 }, \
|
||||
+ { "INFINITx", INFINITY, 3 }, \
|
||||
+ { "infinitx", INFINITY, 3 }, \
|
||||
+ { "INFINITYY", INFINITY, 8 }, \
|
||||
+ { "infinityy", INFINITY, 8 }, \
|
||||
+ { "NANx", NAN, 3 }, \
|
||||
+ { "nanx", NAN, 3 }, \
|
||||
+ { "NAN(", NAN, 3 }, \
|
||||
+ { "nan(", NAN, 3 }, \
|
||||
+ { "NAN(x", NAN, 3 }, \
|
||||
+ { "nan(x", NAN, 3 }, \
|
||||
+ { "NAN(x)y", NAN, 6 }, \
|
||||
+ { "nan(x)y", NAN, 6 }, \
|
||||
+ { "NAN(*)y", NAN, 3 }, \
|
||||
+ { "nan(*)y", NAN, 3 } \
|
||||
}; \
|
||||
\
|
||||
static int \
|
||||
+compare_strto ## FSUF (FTYPE x, FTYPE y) \
|
||||
+{ \
|
||||
+ if (isnan (x) && isnan (y)) \
|
||||
+ return 1; \
|
||||
+ return x == y; \
|
||||
+} \
|
||||
+ \
|
||||
+static int \
|
||||
test_strto ## FSUF (void) \
|
||||
{ \
|
||||
int status = 0; \
|
||||
@@ -30,7 +67,7 @@ test_strto ## FSUF (void) \
|
||||
{ \
|
||||
char *ep; \
|
||||
FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].str, &ep); \
|
||||
- if (r != tests_strto ## FSUF[i].result) \
|
||||
+ if (!compare_strto ## FSUF (r, tests_strto ## FSUF[i].result)) \
|
||||
{ \
|
||||
char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \
|
||||
FTOSTR (buf1, sizeof (buf1), "%g", r); \
|
17
glibc.spec
17
glibc.spec
@ -157,7 +157,7 @@ end \
|
||||
Summary: The GNU libc libraries
|
||||
Name: glibc
|
||||
Version: %{glibcversion}
|
||||
Release: 132%{?dist}
|
||||
Release: 133%{?dist}
|
||||
|
||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||
# libraries.
|
||||
@ -878,6 +878,17 @@ Patch639: glibc-RHEL-46734.patch
|
||||
Patch640: glibc-RHEL-46735.patch
|
||||
Patch641: glibc-RHEL-60466-1.patch
|
||||
Patch642: glibc-RHEL-60466-2.patch
|
||||
Patch643: glibc-RHEL-46739-1.patch
|
||||
Patch644: glibc-RHEL-46739-2.patch
|
||||
Patch645: glibc-RHEL-46739-3.patch
|
||||
Patch646: glibc-RHEL-46739-4.patch
|
||||
Patch647: glibc-RHEL-46739-5.patch
|
||||
Patch648: glibc-RHEL-46739-6.patch
|
||||
Patch649: glibc-RHEL-46739-7.patch
|
||||
Patch650: glibc-RHEL-46739-8.patch
|
||||
Patch651: glibc-RHEL-46739-9.patch
|
||||
Patch652: glibc-RHEL-46739-10.patch
|
||||
Patch653: glibc-RHEL-46739-11.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -3037,6 +3048,10 @@ update_gconv_modules_cache ()
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Sep 30 2024 Arjun Shankar <arjun@redhat.com> - 2.34-133
|
||||
- strtod: Fix subnormal rounding; do not set errno upon overflowing payload;
|
||||
and add several new tests (RHEL-46739)
|
||||
|
||||
* Fri Sep 27 2024 Florian Weimer <fweimer@redhat.com> - 2.34-132
|
||||
- Remove some unused ppc64le string functions (RHEL-60466)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user