git: 8e6843db9bc5 - main - libc: drop NO_FP_LIBC support

From: Xin LI <delphij_at_FreeBSD.org>
Date: Sat, 17 Jan 2026 06:45:13 UTC
The branch main has been updated by delphij:

URL: https://cgit.FreeBSD.org/src/commit/?id=8e6843db9bc5af14b0ee631081ecaf1f02ce821a

commit 8e6843db9bc5af14b0ee631081ecaf1f02ce821a
Author:     Xin LI <delphij@FreeBSD.org>
AuthorDate: 2026-01-17 06:41:56 +0000
Commit:     Xin LI <delphij@FreeBSD.org>
CommitDate: 2026-01-17 06:43:40 +0000

    libc: drop NO_FP_LIBC support
    
    NO_FP_LIBC was added in 2004 to save space by disabling FP support in
    *printf()/*scanf(). The size benefit is negligible on modern systems
    and conflicts with assumptions made by current base utilities.
    
    Remove the option and always build libc with floating-point support.
    
    Reported by:    Oskar Holmlund <eovholmlund at gmail com>
    MFC after:      2 weeks
---
 lib/libc/Makefile                   |  3 ---
 lib/libc/gen/fmtcheck.c             |  4 ----
 lib/libc/stdio/printf-pos.c         | 12 ------------
 lib/libc/stdio/printfcommon.h       |  4 ----
 lib/libc/stdio/printflocal.h        |  2 --
 lib/libc/stdio/vfprintf.c           | 14 --------------
 lib/libc/stdio/vfscanf.c            | 10 ----------
 lib/libc/stdio/vfwprintf.c          | 12 ------------
 lib/libc/stdio/vfwscanf.c           |  8 --------
 lib/libc/stdio/xprintf.c            |  6 ------
 share/man/man5/src.conf.5           |  6 +-----
 share/mk/src.opts.mk                |  1 -
 tools/build/options/WITHOUT_FP_LIBC |  3 ---
 13 files changed, 1 insertion(+), 84 deletions(-)

diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index 34474cfa9fe4..56818e07aa96 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -142,9 +142,6 @@ CFLAGS+= -DYP
 .if ${MK_HESIOD} != "no"
 CFLAGS+= -DHESIOD
 .endif
-.if ${MK_FP_LIBC} == "no"
-CFLAGS+= -DNO_FLOATING_POINT
-.endif
 .if ${MK_NS_CACHING} != "no"
 CFLAGS+= -DNS_CACHING
 .endif
diff --git a/lib/libc/gen/fmtcheck.c b/lib/libc/gen/fmtcheck.c
index de889ad3421c..6d85e3889a4d 100644
--- a/lib/libc/gen/fmtcheck.c
+++ b/lib/libc/gen/fmtcheck.c
@@ -55,10 +55,8 @@ enum __e_fmtcheck_types {
 	FMTCHECK_INTMAXTPOINTER,
 	FMTCHECK_PTRDIFFTPOINTER,
 	FMTCHECK_SIZETPOINTER,
-#ifndef NO_FLOATING_POINT
 	FMTCHECK_DOUBLE,
 	FMTCHECK_LONGDOUBLE,
-#endif
 	FMTCHECK_STRING,
 	FMTCHECK_WSTRING,
 	FMTCHECK_WIDTH,
@@ -185,7 +183,6 @@ get_next_format_from_precision(const char **pf)
 			RETURN(pf,f,FMTCHECK_UNKNOWN);
 		RETURN(pf,f,FMTCHECK_LONG);
 	}
-#ifndef NO_FLOATING_POINT
 	if (strchr("aAeEfFgG", *f)) {
 		switch (modifier) {
 		case MOD_LONGDOUBLE:
@@ -197,7 +194,6 @@ get_next_format_from_precision(const char **pf)
 			RETURN(pf,f,FMTCHECK_UNKNOWN);
 		}
 	}
-#endif
 	if (*f == 'c') {
 		switch (modifier) {
 		case MOD_LONG:
diff --git a/lib/libc/stdio/printf-pos.c b/lib/libc/stdio/printf-pos.c
index edbd4e379699..4fa99316321c 100644
--- a/lib/libc/stdio/printf-pos.c
+++ b/lib/libc/stdio/printf-pos.c
@@ -311,11 +311,9 @@ reswitch:	switch (ch) {
 				goto rflag;
 			}
 			goto reswitch;
-#ifndef NO_FLOATING_POINT
 		case 'L':
 			flags |= LONGDBL;
 			goto rflag;
-#endif
 		case 'h':
 			if (flags & SHORTINT) {
 				flags &= ~SHORTINT;
@@ -359,7 +357,6 @@ reswitch:	switch (ch) {
 			if ((error = addsarg(&types, flags)))
 				goto error;
 			break;
-#ifndef NO_FLOATING_POINT
 		case 'a':
 		case 'A':
 		case 'e':
@@ -372,7 +369,6 @@ reswitch:	switch (ch) {
 			if (error)
 				goto error;
 			break;
-#endif /* !NO_FLOATING_POINT */
 		case 'n':
 			if (flags & INTMAXT)
 				error = addtype(&types, TP_INTMAXT);
@@ -504,11 +500,9 @@ reswitch:	switch (ch) {
 				goto rflag;
 			}
 			goto reswitch;
-#ifndef NO_FLOATING_POINT
 		case 'L':
 			flags |= LONGDBL;
 			goto rflag;
-#endif
 		case 'h':
 			if (flags & SHORTINT) {
 				flags &= ~SHORTINT;
@@ -552,7 +546,6 @@ reswitch:	switch (ch) {
 			if ((error = addsarg(&types, flags)))
 				goto error;
 			break;
-#ifndef NO_FLOATING_POINT
 		case 'a':
 		case 'A':
 		case 'e':
@@ -565,7 +558,6 @@ reswitch:	switch (ch) {
 			if (error)
 				goto error;
 			break;
-#endif /* !NO_FLOATING_POINT */
 		case 'n':
 			if (flags & INTMAXT)
 				error = addtype(&types, TP_INTMAXT);
@@ -744,14 +736,10 @@ build_arg_table(struct typetable *types, va_list ap, union arg **argtable)
 			(*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
 			break;
 		    case T_DOUBLE:
-#ifndef NO_FLOATING_POINT
 			(*argtable) [n].doublearg = va_arg (ap, double);
-#endif
 			break;
 		    case T_LONG_DOUBLE:
-#ifndef NO_FLOATING_POINT
 			(*argtable) [n].longdoublearg = va_arg (ap, long double);
-#endif
 			break;
 		    case TP_CHAR:
 			(*argtable) [n].pchararg = va_arg (ap, char *);
diff --git a/lib/libc/stdio/printfcommon.h b/lib/libc/stdio/printfcommon.h
index 411b778dc234..9de2783c4804 100644
--- a/lib/libc/stdio/printfcommon.h
+++ b/lib/libc/stdio/printfcommon.h
@@ -43,7 +43,6 @@
  */
 
 
-#ifndef NO_FLOATING_POINT
 
 #define	dtoa		__dtoa
 #define	freedtoa	__freedtoa
@@ -57,7 +56,6 @@
 
 static int exponent(CHAR *, int, CHAR);
 
-#endif /* !NO_FLOATING_POINT */
 
 static CHAR	*__ujtoa(uintmax_t, CHAR *, int, int, const char *);
 static CHAR	*__ultoa(u_long, CHAR *, int, int, const char *);
@@ -280,7 +278,6 @@ __ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs)
 	return (cp);
 }
 
-#ifndef NO_FLOATING_POINT
 
 static int
 exponent(CHAR *p0, int exp, CHAR fmtch)
@@ -318,4 +315,3 @@ exponent(CHAR *p0, int exp, CHAR fmtch)
 	return (p - p0);
 }
 
-#endif /* !NO_FLOATING_POINT */
diff --git a/lib/libc/stdio/printflocal.h b/lib/libc/stdio/printflocal.h
index f3d0d3e9e216..f3bedcda6678 100644
--- a/lib/libc/stdio/printflocal.h
+++ b/lib/libc/stdio/printflocal.h
@@ -82,10 +82,8 @@ union arg {
 	ptrdiff_t *pptrdiffarg;
 	ssize_t	*pssizearg;
 	intmax_t *pintmaxarg;
-#ifndef NO_FLOATING_POINT
 	double	doublearg;
 	long double longdoublearg;
-#endif
 	wint_t	wintarg;
 	wchar_t	*pwchararg;
 };
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 2dc8d9022179..a4633ce7837f 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -314,7 +314,6 @@ __vfprintf(FILE *fp, locale_t locale, int serrno, const char *fmt0, va_list ap)
 	char sign;		/* sign prefix (' ', '+', '-', or \0) */
 	struct grouping_state gs; /* thousands' grouping info */
 
-#ifndef NO_FLOATING_POINT
 	/*
 	 * We can decompose the printed representation of floating
 	 * point numbers into several parts, some of which may be empty:
@@ -343,7 +342,6 @@ __vfprintf(FILE *fp, locale_t locale, int serrno, const char *fmt0, va_list ap)
 	int ndig;		/* actual number of digits returned by dtoa */
 	char expstr[MAXEXPDIG+2];	/* buffer for exponent string: e+ZZZ */
 	char *dtoaresult;	/* buffer allocated by dtoa */
-#endif
 	u_long	ulval;		/* integer arguments %[diouxX] */
 	uintmax_t ujval;	/* %j, %ll, %q, %t, %z integers */
 	int base;		/* base for [diouxX] conversion */
@@ -465,12 +463,10 @@ __vfprintf(FILE *fp, locale_t locale, int serrno, const char *fmt0, va_list ap)
 	va_copy(orgap, ap);
 	io_init(&io, fp);
 	ret = 0;
-#ifndef NO_FLOATING_POINT
 	dtoaresult = NULL;
 	decimal_point = localeconv_l(locale)->decimal_point;
 	/* The overwhelmingly common case is decpt_len == 1. */
 	decpt_len = (decimal_point[1] == '\0' ? 1 : strlen(decimal_point));
-#endif
 
 	/*
 	 * Scan the format for conversions (`%' character).
@@ -574,11 +570,9 @@ reswitch:	switch (ch) {
 			}
 			width = n;
 			goto reswitch;
-#ifndef NO_FLOATING_POINT
 		case 'L':
 			flags |= LONGDBL;
 			goto rflag;
-#endif
 		case 'h':
 			if (flags & SHORTINT) {
 				flags &= ~SHORTINT;
@@ -704,7 +698,6 @@ reswitch:	switch (ch) {
 			}
 			base = 10;
 			goto number;
-#ifndef NO_FLOATING_POINT
 		case 'a':
 		case 'A':
 			if (ch == 'a') {
@@ -823,7 +816,6 @@ fp_common:
 					size += grouping_init(&gs, expt, locale);
 			}
 			break;
-#endif /* !NO_FLOATING_POINT */
 		case 'm':
 			error = __strerror_rl(serrno, errnomsg,
 			    sizeof(errnomsg), locale);
@@ -1023,9 +1015,7 @@ invalid:
 			PAD(width - realsz, zeroes);
 
 		/* the string or number proper */
-#ifndef NO_FLOATING_POINT
 		if ((flags & FPT) == 0) {
-#endif
 			/* leading zeroes from decimal precision */
 			PAD(dprec - size, zeroes);
 			if (gs.grouping) {
@@ -1034,7 +1024,6 @@ invalid:
 			} else {
 				PRINT(cp, size);
 			}
-#ifndef NO_FLOATING_POINT
 		} else {	/* glue together f_p fragments */
 			if (!expchar) {	/* %[fF] or sufficiently short %[gG] */
 				if (expt <= 0) {
@@ -1071,7 +1060,6 @@ invalid:
 				PRINT(expstr, expsize);
 			}
 		}
-#endif
 		/* left-adjusting padding (always blank) */
 		if (flags & LADJUST)
 			PAD(width - realsz, blanks);
@@ -1085,10 +1073,8 @@ done:
 	FLUSH();
 error:
 	va_end(orgap);
-#ifndef NO_FLOATING_POINT
 	if (dtoaresult != NULL)
 		freedtoa(dtoaresult);
-#endif
 	if (convbuf != NULL)
 		free(convbuf);
 	if (__sferror(fp))
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index 89e9e843969f..576fe7d80485 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -56,9 +56,7 @@
 #include "local.h"
 #include "xlocale_private.h"
 
-#ifndef NO_FLOATING_POINT
 #include <locale.h>
-#endif
 
 #define	BUF		513	/* Maximum length of numeric string. */
 
@@ -89,9 +87,7 @@
 #define	CT_FLOAT	4	/* %[efgEFG] conversion */
 
 static const u_char *__sccl(char *, const u_char *);
-#ifndef NO_FLOATING_POINT
 static int parsefloat(FILE *, char *, char *, locale_t);
-#endif
 
 __weak_reference(__vfscanf, vfscanf);
 
@@ -648,12 +644,10 @@ literal:
 			base = 16;
 			break;
 
-#ifndef NO_FLOATING_POINT
 		case 'A': case 'E': case 'F': case 'G':
 		case 'a': case 'e': case 'f': case 'g':
 			c = CT_FLOAT;
 			break;
-#endif
 
 		case 'S':
 			flags |= LONG;
@@ -835,7 +829,6 @@ literal:
 			}
 			break;
 
-#ifndef NO_FLOATING_POINT
 		case CT_FLOAT:
 			/* scan a floating point number as if by strtod */
 			if (width == 0 || width > sizeof(buf) - 1)
@@ -858,7 +851,6 @@ literal:
 				}
 			}
 			break;
-#endif /* !NO_FLOATING_POINT */
 		}
 		if (!(flags & SUPPRESS))
 			nassigned++;
@@ -984,7 +976,6 @@ doswitch:
 	/* NOTREACHED */
 }
 
-#ifndef NO_FLOATING_POINT
 static int
 parsefloat(FILE *fp, char *buf, char *end, locale_t locale)
 {
@@ -1153,4 +1144,3 @@ parsedone:
 	*++commit = '\0';
 	return (commit - buf);
 }
-#endif
diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c
index 0d77bd74567e..f5324915ec3e 100644
--- a/lib/libc/stdio/vfwprintf.c
+++ b/lib/libc/stdio/vfwprintf.c
@@ -389,7 +389,6 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap)
 	int prec;		/* precision from format; <0 for N/A */
 	wchar_t sign;		/* sign prefix (' ', '+', '-', or \0) */
 	struct grouping_state gs; /* thousands' grouping info */
-#ifndef NO_FLOATING_POINT
 	/*
 	 * We can decompose the printed representation of floating
 	 * point numbers into several parts, some of which may be empty:
@@ -417,7 +416,6 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap)
 	int ndig;		/* actual number of digits returned by dtoa */
 	wchar_t expstr[MAXEXPDIG+2];	/* buffer for exponent string: e+ZZZ */
 	char *dtoaresult;	/* buffer allocated by dtoa */
-#endif
 	u_long	ulval;		/* integer arguments %[diouxX] */
 	uintmax_t ujval;	/* %j, %ll, %q, %t, %z integers */
 	int base;		/* base for [diouxX] conversion */
@@ -537,9 +535,7 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap)
 	va_copy(orgap, ap);
 	io_init(&io, fp);
 	ret = 0;
-#ifndef NO_FLOATING_POINT
 	decimal_point = get_decpt(locale);
-#endif
 
 	/*
 	 * Scan the format for conversions (`%' character).
@@ -643,11 +639,9 @@ reswitch:	switch (ch) {
 			}
 			width = n;
 			goto reswitch;
-#ifndef NO_FLOATING_POINT
 		case 'L':
 			flags |= LONGDBL;
 			goto rflag;
-#endif
 		case 'h':
 			if (flags & SHORTINT) {
 				flags &= ~SHORTINT;
@@ -761,7 +755,6 @@ reswitch:	switch (ch) {
 			}
 			base = 10;
 			goto number;
-#ifndef NO_FLOATING_POINT
 		case 'a':
 		case 'A':
 			if (ch == 'a') {
@@ -885,7 +878,6 @@ fp_common:
 					size += grouping_init(&gs, expt, locale);
 			}
 			break;
-#endif /* !NO_FLOATING_POINT */
 		case 'n':
 			/*
 			 * Assignment-like behavior is specified if the
@@ -1080,9 +1072,7 @@ invalid:
 			PAD(width - realsz, zeroes);
 
 		/* the string or number proper */
-#ifndef NO_FLOATING_POINT
 		if ((flags & FPT) == 0) {
-#endif
 			/* leading zeroes from decimal precision */
 			PAD(dprec - size, zeroes);
 			if (gs.grouping) {
@@ -1091,7 +1081,6 @@ invalid:
 			} else {
 				PRINT(cp, size);
 			}
-#ifndef NO_FLOATING_POINT
 		} else {	/* glue together f_p fragments */
 			if (!expchar) {	/* %[fF] or sufficiently short %[gG] */
 				if (expt <= 0) {
@@ -1129,7 +1118,6 @@ invalid:
 				PRINT(expstr, expsize);
 			}
 		}
-#endif
 		/* left-adjusting padding (always blank) */
 		if (flags & LADJUST)
 			PAD(width - realsz, blanks);
diff --git a/lib/libc/stdio/vfwscanf.c b/lib/libc/stdio/vfwscanf.c
index 7ca64eb37811..dbe7c6c48c98 100644
--- a/lib/libc/stdio/vfwscanf.c
+++ b/lib/libc/stdio/vfwscanf.c
@@ -84,9 +84,7 @@
 #define	CT_INT		3	/* %[dioupxX] conversion */
 #define	CT_FLOAT	4	/* %[efgEFG] conversion */
 
-#ifndef NO_FLOATING_POINT
 static int parsefloat(FILE *, wchar_t *, wchar_t *, locale_t);
-#endif
 
 struct ccl {
 	const wchar_t *start;	/* character class start */
@@ -630,12 +628,10 @@ literal:
 			base = 16;
 			break;
 
-#ifndef NO_FLOATING_POINT
 		case 'A': case 'E': case 'F': case 'G':
 		case 'a': case 'e': case 'f': case 'g':
 			c = CT_FLOAT;
 			break;
-#endif
 
 		case 'S':
 			flags |= LONG;
@@ -813,7 +809,6 @@ literal:
 			}
 			break;
 
-#ifndef NO_FLOATING_POINT
 		case CT_FLOAT:
 			/* scan a floating point number as if by strtod */
 			if (width == 0 || width > sizeof(buf) /
@@ -835,7 +830,6 @@ literal:
 				}
 			}
 			break;
-#endif /* !NO_FLOATING_POINT */
 		}
 		if (!(flags & SUPPRESS))
 			nassigned++;
@@ -848,7 +842,6 @@ match_failure:
 	return (nassigned);
 }
 
-#ifndef NO_FLOATING_POINT
 static int
 parsefloat(FILE *fp, wchar_t *buf, wchar_t *end, locale_t locale)
 {
@@ -1007,4 +1000,3 @@ parsedone:
 	*++commit = '\0';
 	return (commit - buf);
 }
-#endif
diff --git a/lib/libc/stdio/xprintf.c b/lib/libc/stdio/xprintf.c
index a5671db67f58..4af0425792b0 100644
--- a/lib/libc/stdio/xprintf.c
+++ b/lib/libc/stdio/xprintf.c
@@ -60,10 +60,8 @@ union arg {
 	int			intarg;
 	long			longarg;
 	intmax_t 		intmaxarg;
-#ifndef NO_FLOATING_POINT
 	double			doublearg;
 	long double 		longdoublearg;
-#endif
 	wint_t			wintarg;
 	char			*pchararg;
 	wchar_t			*pwchararg;
@@ -497,14 +495,10 @@ __v2printf(FILE *fp, const char *fmt0, unsigned pct, va_list ap)
 			args[ch].pwchararg = va_arg (ap, wchar_t *);
 			break;
 		case PA_DOUBLE:
-#ifndef NO_FLOATING_POINT
 			args[ch].doublearg = va_arg (ap, double);
-#endif
 			break;
 		case PA_DOUBLE | PA_FLAG_LONG_DOUBLE:
-#ifndef NO_FLOATING_POINT
 			args[ch].longdoublearg = va_arg (ap, long double);
-#endif
 			break;
 		default:
 			errx(1, "argtype = %x (fmt = \"%s\")\n",
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 81c1b3e88dc3..339ca2bd3e8f 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1,5 +1,5 @@
 .\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman.
-.Dd January 12, 2026
+.Dd January 16, 2026
 .Dt SRC.CONF 5
 .Os
 .Sh NAME
@@ -761,10 +761,6 @@ when compiling the kernel.
 Also disables all format checking.
 .It Va WITHOUT_FORTH
 Build bootloaders without Forth support.
-.It Va WITHOUT_FP_LIBC
-Build
-.Nm libc
-without floating-point support.
 .It Va WITHOUT_FREEBSD_UPDATE
 Do not build
 .Xr freebsd-update 8 .
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index 99a70bc4239f..f8ef63130326 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -99,7 +99,6 @@ __DEFAULT_YES_OPTIONS = \
     FINGER \
     FLOPPY \
     FORTH \
-    FP_LIBC \
     FREEBSD_UPDATE \
     FTP \
     GAMES \
diff --git a/tools/build/options/WITHOUT_FP_LIBC b/tools/build/options/WITHOUT_FP_LIBC
deleted file mode 100644
index c92a9f82fcaf..000000000000
--- a/tools/build/options/WITHOUT_FP_LIBC
+++ /dev/null
@@ -1,3 +0,0 @@
-Build
-.Nm libc
-without floating-point support.