| Summary: | Conversion from long to long double is broken | ||
|---|---|---|---|
| Product: | Base System | Reporter: | kettenis <kettenis> |
| Component: | sparc64 | Assignee: | Stefan Farfeleder <stefanf> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 5.1-CURRENT | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-sparc64->jake I'll look into this. By the looks of it, this bug also affects /usr/ports/net/isc-dhcp3-server
After spending 3 days pulling my hair out trying to get DDNS working with
bind/dhcpd - I noticed the following in /var/db/dhcpd/dhcpd.leases
--
lease 192.168.55.32 {
starts 5 -371915209/03/05 13:33:03;
ends 5 -371915209/03/05 13:43:03;
tstp 5 -371915209/03/05 13:43:03;
binding state free;
hardware ethernet 00:0a:e6:d0:4e:de;
uid "\001\000\012\346\320N\336";
}
--
It seems to me that this bug is causing DHCPD to mangle dates used by the
daemon.
--
___//____\\___//____\\___\\___//____\\___//____\\___//____\\___//____\\
Charlie Livingston "What we need to do is take the warning
charlie@sysninjas.com labels off of everything and let the
http://sysninjas.com problem of stupidity solve itself"
- Unknown Author
Responsible Changed From-To: jake->stefanf Over to me. State Changed From-To: open->patched A fix has been committed to current, thanks for the report. State Changed From-To: patched->closed Fix merged to stable. |
Conversion of `long' and `unsigned long' to `long double' are broken on FreeBSD/sparc64. GCC generates the right code AFAICT, but the implementation of _Qp_xtoq() and _Qp_uxtoq() in /src/lib/libc/sparc64/fpu/fpu_qp.c seem to be broken. Every value that has bit 32 set will be negative when converted to a `long double'. Fix: Looking at the code in /usr/src/lib/libc/sparc64/fpu/fpu_qp.c (I'm looking at revision 1.3), it seems that the _QP_TTOQ() macro only handles 32-bit signed integers since on line 63 of that file we have: fe.fe_f1.fp_sign = a[0] >> 31; I think that this line should be fe.fe_f1.fp_sign = a[0] >> 63; for `long' (_Qp_xtoq) and that the line should be completely absent for `unsigned' (_Qp_uitoq) and `unsigned long' (_Qp_uxtoq). Some not-too-thorough testing seems to indicate that's right. How-To-Repeat: The following test program exhibits the behaviour: #include <stdio.h> unsigned long mant_long = 0x80000000; int main (void) { long double mant = mant_long; printf ("%lu\n", mant_long); printf ("%Lf\n", mant); return 0; } which should print 2147483648 2147483648.000000 but will print 2147483648 -2147483648.000000