[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Make check - test-vasprintf-posix failure - darwin12 - macos
From: |
Bruno Haible |
Subject: |
Re: Make check - test-vasprintf-posix failure - darwin12 - macos |
Date: |
Tue, 21 May 2024 03:46:53 +0200 |
Gaëtan HERFRAY wrote and Eric Blake forwarded in
<https://lists.gnu.org/archive/html/bug-gnulib/2022-03/msg00066.html>:
> > Actually, make check is failing on test-vasprintf-posix.
>
> Thanks for the report. This test is maintained by gnulib, so other
> projects may see the same failure in that test. Or it may have been
> fixed in the meantime (I still need to release an updated version of
> m4).
>
> > After investigating, I found that they are 3 tests that are failing, about
> > pseudo denormal (you can find the four tests by looking for "{ LDBL80_WORDS
> > (0x0000, 0x83333333, 0x00000000) }".
> >
> > Only the first one pass, the three next are failing.
> >
> > First question: are those tests important?
>
> They are important to gnulib, as it helps find places where we still
> need to work around platform bugs. But they are less important to m4,
> which does not output floating point numbers, and therefore does not
> need to worry about printf() bugs in dealing with pseudo-denormal bit
> values.
Sorry for the long delay. I can reproduce the issue with CI tests on
some macOS 12 machine. There, I get this unit test output:
FAIL: test-vasnprintf-posix
===========================
Stack trace:
0x105a3f33f print_stack_trace
../../gllib/abort-debug.c:40
0x105a3f33f rpl_abort
../../gllib/abort-debug.c:94
0x105a46f30 floorlog10l
../../gllib/vasnprintf.c:1450
0x105a41e70 vasnprintf
../../gllib/vasnprintf.c:4571
0x105a3f271 my_asnprintf
../../gltests/test-vasnprintf-posix.c:5252
0x105a28318 test_function
../../gltests/test-vasnprintf-posix.c:1568
0x105a1f2ff test_vasnprintf
../../gltests/test-vasnprintf-posix.c:5260
0x105a1f2ff main
../../gltests/test-vasnprintf-posix.c:5272
FAIL test-vasnprintf-posix (exit status: 134)
It seems that the macOS 12 'frexpl' function does not handle the
pseudo-denormal values appropriately. The patch below fixes the test failures.
Note: While investigating the *printf results on pseudo-denormal values,
I found that glibc does not do it consistently:
<https://sourceware.org/bugzilla/show_bug.cgi?id=31769>.
2024-05-20 Bruno Haible <bruno@clisp.org>
vasnprintf: Don't abort for pseudo-denormal arguments on macOS 12.
Reported by Gaëtan Herfray <g.herfray@gahfy.io> via Erik Blake in
<https://lists.gnu.org/archive/html/bug-m4/2022-03/msg00002.html>
<https://lists.gnu.org/archive/html/bug-gnulib/2022-03/msg00066.html>.
* lib/vasnprintf.c (safe_frexpl): New function.
(decode_long_double, floorlog10l): Invoke it instead of frexpl.
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 6f06273081..ac8dc8619e 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -86,7 +86,7 @@
#include <wchar.h> /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb(),
mbszero() */
#include <errno.h> /* errno */
#include <limits.h> /* CHAR_BIT, INT_WIDTH, LONG_WIDTH */
-#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
+#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP, LDBL_MANT_DIG */
#if HAVE_NL_LANGINFO
# include <langinfo.h>
#endif
@@ -406,6 +406,40 @@ is_infinite_or_zerol (long double x)
#endif
+#if NEED_PRINTF_LONG_DOUBLE
+
+/* Like frexpl, except that it supports even "unsupported" numbers. */
+# if (LDBL_MANT_DIG == 64 && (defined __ia64 || (defined __x86_64__ || defined
__amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined
_M_IX86 || defined _X86_))) && (defined __APPLE__ && defined __MACH__)
+/* Don't assume that frexpl can handle pseudo-denormals; it does not on
+ macOS 12/x86_64. Therefore test for a pseudo-denormal explicitly. */
+
+static
+long double safe_frexpl (long double x, int *exp)
+{
+ union
+ {
+ long double value;
+ struct { unsigned int mant_word[2]; unsigned short sign_exp_word; } r;
+ }
+ u;
+ u.value = x;
+ if (u.r.sign_exp_word == 0 && (u.r.mant_word[1] & 0x80000000u) != 0)
+ {
+ /* Pseudo-Denormal. */
+ *exp = LDBL_MIN_EXP;
+ u.r.sign_exp_word = 1 - LDBL_MIN_EXP;
+ return u.value;
+ }
+ else
+ return frexpl (x, exp);
+}
+
+# else
+# define safe_frexpl frexpl
+# endif
+
+#endif
+
#if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE
/* An indicator for a failed memory allocation. */
@@ -1018,7 +1052,7 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
if (m.limbs == NULL)
return NULL;
/* Split into exponential part and mantissa. */
- y = frexpl (x, &exp);
+ y = safe_frexpl (x, &exp);
if (!(y >= 0.0L && y < 1.0L))
abort ();
/* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
@@ -1445,7 +1479,7 @@ floorlog10l (long double x)
double l;
/* Split into exponential part and mantissa. */
- y = frexpl (x, &exp);
+ y = safe_frexpl (x, &exp);
if (!(y >= 0.0L && y < 1.0L))
abort ();
if (y == 0.0L)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: Make check - test-vasprintf-posix failure - darwin12 - macos,
Bruno Haible <=