glibc/glibc-upstream-2.39-136.patch
Arjun Shankar 2a30b8f4b2 Sync with upstream branch release/2.39/master
Upstream commit: dcaf51b41e259387602774829c45222d0507f90a

- elf: Change ldconfig auxcache magic number (bug 32231)
- Make tst-strtod-underflow type-generic
- Add crt1-2.0.o for glibc 2.0 compatibility tests
- Add tests of more strtod special cases
- Add more tests of strtod end pointer
- Make tst-strtod2 and tst-strtod5 type-generic
- powerpc64le: Build new strtod tests with long double ABI flags (bug 32145)
- Do not set errno for overflowing NaN payload in strtod/nan (bug 32045)
- Improve NaN payload testing
- Make __strtod_internal tests type-generic
- Fix strtod subnormal rounding (bug 30220)
- More thoroughly test underflow / errno in tst-strtod-round
- Test errno setting on strtod overflow in tst-strtod-round
- Add tests of fread
- stdio-common: Add new test for fdopen
- libio: Attempt wide backup free only for non-legacy code
- debug: Fix read error handling in pcprofiledump
- elf: Fix tst-dlopen-tlsreinit1.out test dependency
- elf: Avoid re-initializing already allocated TLS in dlopen (bug 31717)
- elf: Clarify and invert second argument of _dl_allocate_tls_init
- elf: Support recursive use of dynamic TLS in interposed malloc
- nptl: Use <support/check.h> facilities in tst-setuid3
- posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64
- ungetc: Fix backup buffer leak on program exit [BZ #27821]
- ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]
- Make tst-ungetc use libsupport
- stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650]
- support: Add FAIL test failure helper
- string: strerror, strsignal cannot use buffer after dlmopen (bug 32026)
- Define __libc_initial for the static libc
- x86: Fix bug in strchrnul-evex512 [BZ #32078]
- Adjust check-local-headers test for libaudit 4.0
- x32/cet: Support shadow stack during startup for Linux 6.10
- x86-64: Remove sysdeps/x86_64/x32/dl-machine.h
- support: Add options list terminator to the test driver
- manual/stdio: Further clarify putc, putwc, getc, and getwc
- Fix name space violation in fortify wrappers (bug 32052)
- resolv: Fix tst-resolv-short-response for older GCC (bug 32042)
- Add mremap tests
- mremap: Update manual entry
- linux: Update the mremap C implementation [BZ #31968]
- Enhanced test coverage for strncmp, wcsncmp
- Enhance test coverage for strnlen, wcsnlen

Resolves: RHEL-57776
Resolves: RHEL-57777
Resolves: RHEL-61392
2024-11-20 17:12:17 +01:00

442 lines
14 KiB
Diff

commit b3c51635efb532dd0544e6f4dedd6a184f0ae1a2
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.
(cherry picked from commit 94ca2c0894f0e1b62625c369cc598a2b9236622c)
diff --git a/stdlib/tst-strtod-underflow.c b/stdlib/tst-strtod-underflow.c
index a5ced18599bbf985..8598b95b6da7fd40 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);
}