It doesn't work. It's undefined behaviour. On NetBSD, it will fail
with EBADF, if fd 0 isn't open for write, or if fd 0 is open for
write, it will write heap garbage to fd 0.
If stream points to an output stream or an update stream in which
the most recent operation was not input, the fflush function causes
any unwritten data for that stream to be delivered to the host
environment to be written to the file; otherwise, the behavior is
undefined.
(ISO C11 and ISO C17, Sec. 7.21.5.2 `The fflush function')
PR lib/58206
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114879
No floating-point exception traps on RISC-V.
Also don't pass the result of divide-by-zero converted to integer to
usleep. Although the floating-point result of divide-by-zero is
well-defined by IEEE 754 (+/-infinity), the outcome of C conversion
to integer is not. And while on some architectures this might return
zero, on RISC-V it looks like it'll return all bits set. And as of
PR 58184, usleep now honours sleeps longer than 1sec, which means
this will be waiting at least two billion microseconds, or about half
an hour...
So instead, just write the result to a volatile variable.
Also add comments explaining how I generated these test cases.
(No autoconf back doors hidden in these magic numbers, I promise! No
pythagoreans were harmed in the production of these tests either.)
This test, to verify nexttoward(x, x*(1 - LDBL_EPSILON/2)) moves in
the direction of x*(1 - LDBL_EPSILON/2), only makes sense if long
double has more precision than double -- the point of the exercise is
to verify that nexttoward moves even if the direction parameter can't
be rounded to double. But if long double is just double, this test
makes no sense.
Even though 0 is not a boolean constant, allow this common idiom, to
help in those cases where the C preprocessor used by lint does not mark
tokens as coming from system headers (Clang).
1. Need <math.h> for __HAVE_LONG_DOUBLE.
2. Need <machine/ieee.h> for struct ieee_ext_u &c.
3. EXT_FRACLBITS, not LDBL_MANL_SIZE.
PR lib/58245: hypotl is broken on ld128 ports
By this point in the logic, x can't be zero, so it's either positive
or negative.
The high word hx, however, can be zero, when x is a small positive
subnormal. This means x is a small positive subnormal, so if x > y
we are computing nextDown, and if x < y we are computing nextUp.
hx is a (signed 32-bit) integer, not a double floating-point number,
so it's a little silly to compare hx > 0.0. But that on its own
isn't enough to trigger the bug because all signed 32-bit integers
can be represented by double on all NetBSD architectures.
PR lib/58236
Noted by kre.
This doesn't break a passing test or fix a failed test, at least on
x86 -- our printf produces `0x1.533p+3' for the double case and
`0xa.99ap+0' for the long double case. But of the hexadecimal number
literals that that start with 0x5 having three hexadigits to the
right of the fractional point, 0x5.4cdp+1 closest to the IEEE 754
binary64, VAX D, x86 extended precision, and IEEE 754 binary128
floating-point numbers closest to 10.6.
The reason is that the number 10.6 (or the nearest floating-point
number in any format with enough precision) is:
101.0100 1100 1100|1100... * 2^1 = 0x5.4cc|c...p+1
If we round at the vertical bar to the _nearest_ output with three
hexadigits of precision, the result is:
101.0100 1100 1101 * 2^1 = 0x5.4cdp+1
LDBL_MAX is always defined, so this branch is dead. (If LDBL_MAX is
not defined, that's a bug in the architecture's float.h, not a reason
to skip a test.)
This reverts:
hdtoa.c 1.12 (PR/56247: Greg A. Woods: printf("%La", LDBL_MIN) dumps core)
hdtoa.c 1.11 (fix tyop)
hdtoa.c 1.10 (Via enh at google dot com in tech-userlevel. Fix handling of
EXT_FRAC{H,L}BITS (although we don't need to since we don't have them).)
The underlying motivation for this change was that when ld128 is
decomposed into 4x32 words, this hldtoa logic is broken.
But we don't decompose ld128 into 4x32 words; we decompose it into
6x64 words.
And the change, which was supposed to be a noop in our case of 2x64
words (or similar for x87 80-bit floating-point), broke it to the
point of causing buffer overruns (PR 56247) which when worked around
led to just incorrect output output (PR 56937).
If we want to make the #ifdefs for 4x32 words work, that's fine, but
we absolutely must have automatic test cases to detect this kind of
regression because %La formatting is extremely important for
diagnosing details of floating-point data since it doesn't involve
rounding in binary formats. For now I've added some trivial tests;
there is a more extensive test suite inside gdtoa that we need to
wire up before anyone tries any other shenanigans in this code.
PR lib/56937: printf(3) long double %a formatting is broken
1. Instead of calling out VAX by name, use #ifdef NAN and
isinf(INFINITY). (VAX defines INFINITY even though it's not an
infinity, not sure if there's a better compile-time test.)
2. Verify ilogbl works on long double on all architectures, not just
those with __HAVE_LONG_DOUBLE which means long double is _larger_
than double.
This one was adapted from the screw case shown in
https://mail-index.netbsd.org/tech-userlevel/2020/04/11/msg012329.html
which wasn't broken in our libc, but which nevertheless prompted us
to commit a wrong and apparently untested patch that has rendered
printf %La broken for the last four years, which is a little
embarrassing. (The part of that patch that led to a buffer overrun
has been worked around, so now the output is just incorrect.)
PR lib/56937: printf(3) long double %a formatting is broken
The tests in C11 and C23 mode look the same right now but will change
soon.
The warnings in the C11 test disappeared because after the first error,
warnings about unused variables are suppressed by check_variable_usage,
as they are often wrong.