Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc PR/57250: Martin Husemann: dtoa mishandles infinite...



details:   https://anonhg.NetBSD.org/src/rev/5c30e547f4e7
branches:  trunk
changeset: 374154:5c30e547f4e7
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Apr 04 19:26:06 2023 +0000

description:
PR/57250: Martin Husemann: dtoa mishandles infinite doubles on 32bit big
endian machines. When long double support was added, the old code was kept
for the regular double code. This code was never used because WIDE_DOUBLE
was always defined in the Makefile. Remove that old code, and conditionalize
the WIDE_DOUBLE code based on if long doubles are different than doubles on
the specific platform.

diffstat:

 lib/libc/include/extern.h   |   10 ++-
 lib/libc/stdio/Makefile.inc |    4 +-
 lib/libc/stdio/vfwprintf.c  |  134 +++----------------------------------------
 3 files changed, 21 insertions(+), 127 deletions(-)

diffs (259 lines):

diff -r 86228df5b11e -r 5c30e547f4e7 lib/libc/include/extern.h
--- a/lib/libc/include/extern.h Mon Apr 03 21:35:59 2023 +0000
+++ b/lib/libc/include/extern.h Tue Apr 04 19:26:06 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: extern.h,v 1.26 2020/05/15 14:37:21 joerg Exp $        */
+/*     $NetBSD: extern.h,v 1.27 2023/04/04 19:26:06 christos Exp $     */
 
 /*
  * Copyright (c) 1997 Christos Zoulas.  All rights reserved.
@@ -49,11 +49,17 @@ struct sigaction;
 int __sigaction_sigtramp(int, const struct sigaction *,
     struct sigaction *, const void *, int);
 
+/* is "long double" and "double" different? */
+#if (__LDBL_MANT_DIG__ != __DBL_MANT_DIG__) || \
+    (__LDBL_MAX_EXP__ != __DBL_MAX_EXP__)
+#define WIDE_DOUBLE
+#endif
+
 #ifdef WIDE_DOUBLE
-char *__hdtoa(double, const char *, int, int *, int *, char **);
 char *__hldtoa(long double, const char *, int, int *, int *,  char **);
 char *__ldtoa(long double *, int, int, int *, int *, char **);
 #endif
+char *__hdtoa(double, const char *, int, int *, int *, char **);
 
 #ifndef __LIBC12_SOURCE__
 struct syslog_data;
diff -r 86228df5b11e -r 5c30e547f4e7 lib/libc/stdio/Makefile.inc
--- a/lib/libc/stdio/Makefile.inc       Mon Apr 03 21:35:59 2023 +0000
+++ b/lib/libc/stdio/Makefile.inc       Tue Apr 04 19:26:06 2023 +0000
@@ -1,11 +1,9 @@
 #      from: @(#)Makefile.inc  5.7 (Berkeley) 6/27/91
-#      $NetBSD: Makefile.inc,v 1.47 2015/12/29 17:55:23 christos Exp $
+#      $NetBSD: Makefile.inc,v 1.48 2023/04/04 19:26:06 christos Exp $
 
 # stdio sources
 .PATH: ${.CURDIR}/stdio
 
-CPPFLAGS+=-DWIDE_DOUBLE
-
 SRCS+= clrerr.c dprintf.c fclose.c fdopen.c feof.c ferror.c \
        fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetstr.c fgetwc.c \
        fgetwln.c fgetws.c fileno.c findfp.c flags.c flockfile.c fopen.c \
diff -r 86228df5b11e -r 5c30e547f4e7 lib/libc/stdio/vfwprintf.c
--- a/lib/libc/stdio/vfwprintf.c        Mon Apr 03 21:35:59 2023 +0000
+++ b/lib/libc/stdio/vfwprintf.c        Tue Apr 04 19:26:06 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfwprintf.c,v 1.39 2022/04/19 20:32:16 rillig Exp $    */
+/*     $NetBSD: vfwprintf.c,v 1.40 2023/04/04 19:26:06 christos Exp $  */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -38,7 +38,7 @@
 static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
 __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.27 2007/01/09 00:28:08 imp Exp $");
 #else
-__RCSID("$NetBSD: vfwprintf.c,v 1.39 2022/04/19 20:32:16 rillig Exp $");
+__RCSID("$NetBSD: vfwprintf.c,v 1.40 2023/04/04 19:26:06 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -581,9 +581,6 @@ WDECL(vf,printf_l)(FILE * __restrict fp,
 #define        DEFPREC         6
 
 static int exponent(CHAR_T *, int, int);
-#ifndef WIDE_DOUBLE
-static char *cvt(double, int, int, char *, int *, int, int *);
-#endif
 
 #endif /* !NO_FLOATING_POINT */
 
@@ -649,17 +646,14 @@ WDECL(__vf,printf_unlocked_l)(FILE *fp, 
         * F:   at least two digits for decimal, at least one digit for hex
         */
        char *decimal_point;    /* locale specific decimal point */
-#ifdef WIDE_DOUBLE
        int signflag;           /* true if float is negative */
        union {                 /* floating point arguments %[aAeEfFgG] */
                double dbl;
+#ifdef WIDE_DOUBLE
                long double ldbl;
+#endif
        } fparg;
        char *dtoaend;          /* pointer to end of converted digits */
-#else
-       double _double;         /* double precision arguments %[eEfgG] */
-       char softsign;          /* temporary negative sign for floats */
-#endif
        char *dtoaresult;       /* buffer allocated by dtoa */
        int expt;               /* integer value of exponent */
        char expchar;           /* exponent character: [eEpP\0] */
@@ -1058,7 +1052,6 @@ reswitch: switch (ch) {
                        base = 10;
                        goto number;
 #ifndef NO_FLOATING_POINT
-#ifdef WIDE_DOUBLE
                case 'a':
                case 'A':
                        if (ch == 'a') {
@@ -1072,12 +1065,15 @@ reswitch:       switch (ch) {
                        }
                        if (prec >= 0)
                                prec++;
+#ifdef WIDE_DOUBLE
                        if (flags & LONGDBL) {
                                fparg.ldbl = GETARG(long double);
                                dtoaresult =
                                    __hldtoa(fparg.ldbl, xdigs, prec,
                                        &expt, &signflag, &dtoaend);
-                       } else {
+                       } else
+#endif
+                       {
                                fparg.dbl = GETARG(double);
                                dtoaresult =
                                    __hdtoa(fparg.dbl, xdigs, prec,
@@ -1127,12 +1123,15 @@ reswitch:       switch (ch) {
 fp_begin:
                        if (prec < 0)
                                prec = DEFPREC;
+#ifdef WIDE_DOUBLE
                        if (flags & LONGDBL) {
                                fparg.ldbl = GETARG(long double);
                                dtoaresult =
                                    __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
                                    &expt, &signflag, &dtoaend);
-                       } else {
+                       } else
+#endif
+                       {
                                fparg.dbl = GETARG(double);
                                dtoaresult =
                                    __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
@@ -1170,66 +1169,7 @@ fp_common:
                                flags &= ~ZEROPAD;
                                break;
                        }
-#else
-               case 'e':
-               case 'E':
-               case 'f':
-               case 'F':
-               case 'g':
-               case 'G':
-                       if (prec == -1) {
-                               prec = DEFPREC;
-                       } else if ((ch == 'g' || ch == 'G') && prec == 0) {
-                               prec = 1;
-                       }
 
-                       if (flags & LONGDBL) {
-                               _double = (double) GETARG(long double);
-                       } else {
-                               _double = GETARG(double);
-                       }
-
-                       /* do this before tricky precision changes */
-                       if (isinf(_double)) {
-                               if (_double < 0)
-                                       sign = '-';
-                               if (ch == 'E' || ch == 'F' || ch == 'G')
-                                       result = STRCONST("INF");
-                               else
-                                       result = STRCONST("inf");
-                               size = 3;
-                               flags &= ~ZEROPAD;
-                               break;
-                       }
-                       if (isnan(_double)) {
-                               if (ch == 'E' || ch == 'F' || ch == 'G')
-                                       result = STRCONST("NAN");
-                               else
-                                       result = STRCONST("nan");
-                               size = 3;
-                               flags &= ~ZEROPAD;
-                               break;
-                       }
-
-                       flags |= FPT;
-                       dtoaresult = cvt(_double, prec, flags, &softsign,
-                           &expt, ch, &ndig);
-                       if (dtoaresult == NULL)
-                               goto oomem;
-                       if (convbuf != NULL)
-                               free(convbuf);
-#ifndef NARROW
-                       result = convbuf = __mbsconv(dtoaresult, -1, loc);
-#else
-                       /*XXX inefficient*/
-                       result = convbuf = strdup(dtoaresult);
-#endif
-                       if (result == NULL)
-                               goto oomem;
-                       __freedtoa(dtoaresult);
-                       if (softsign)
-                               sign = '-';
-#endif
                        flags |= FPT;
                        if (ch == 'g' || ch == 'G') {
                                if (expt > -4 && expt <= prec) {
@@ -2001,57 +1941,7 @@ static int
        return 0;
 }
 
-
 #ifndef NO_FLOATING_POINT
-#ifndef WIDE_DOUBLE
-static char *
-cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch,
-    int *length)
-{
-       int mode, dsgn;
-       char *digits, *bp, *rve;
-
-       _DIAGASSERT(decpt != NULL);
-       _DIAGASSERT(length != NULL);
-       _DIAGASSERT(sign != NULL);
-
-       if (ch == 'f') {
-               mode = 3;               /* ndigits after the decimal point */
-       } else {
-               /* To obtain ndigits after the decimal point for the 'e' 
-                * and 'E' formats, round to ndigits + 1 significant 
-                * figures.
-                */
-               if (ch == 'e' || ch == 'E') {
-                       ndigits++;
-               }
-               mode = 2;               /* ndigits significant digits */
-       }
-
-       digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
-       if (digits == NULL)
-               return NULL;
-       if (dsgn) {
-               value = -value;
-               *sign = '-';
-       } else
-               *sign = '\000';
-       if ((ch != 'g' && ch != 'G') || flags & ALT) {  /* Print trailing zeros */
-               bp = digits + ndigits;
-               if (ch == 'f') {
-                       if (*digits == '0' && value)
-                               *decpt = -ndigits + 1;
-                       bp += *decpt;
-               }
-               if (value == 0) /* kludge for __dtoa irregularity */
-                       rve = bp;
-               while (rve < bp)
-                       *rve++ = '0';
-       }
-       *length = rve - digits;
-       return digits;
-}
-#endif
 
 static int
 exponent(CHAR_T *p0, int expo, int fmtch)



Home | Main Index | Thread Index | Old Index