push sheeet
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s

This commit is contained in:
Dark Steveneq
2025-10-09 14:15:47 +02:00
commit 646b892680
49168 changed files with 5897842 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
From 8c9602e3a145e9596dc1a63c6ed67865814b6633 Mon Sep 17 00:00:00 2001
From: Pádraig Brady <P@draigBrady.com>
Date: Tue, 20 May 2025 16:03:44 +0100
Subject: sort: fix buffer under-read (CWE-127)
* src/sort.c (begfield): Check pointer adjustment
to avoid Out-of-range pointer offset (CWE-823).
(limfield): Likewise.
* tests/sort/sort-field-limit.sh: Add a new test,
which triggers with ASAN or Valgrind.
* tests/local.mk: Reference the new test.
* NEWS: Mention bug fix introduced in v7.2 (2009).
Fixes https://bugs.gnu.org/78507
---
NEWS | 5 +++++
src/sort.c | 12 ++++++++++--
tests/local.mk | 1 +
tests/sort/sort-field-limit.sh | 35 +++++++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+), 2 deletions(-)
create mode 100755 tests/sort/sort-field-limit.sh
The new tests is NOT added in NixOS.
diff --git a/NEWS b/NEWS
index 6ff403206..923aa72f8 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,11 @@ GNU coreutils NEWS -*- outline -*-
copying to non-NFS files from NFSv4 files with trivial ACLs.
[bug introduced in coreutils-9.6]
+ sort with key character offsets of SIZE_MAX, could induce
+ a read of 1 byte before an allocated heap buffer. For example:
+ 'sort +0.18446744073709551615R input' on 64 bit systems.
+ [bug introduced in coreutils-7.2]
+
* Noteworthy changes in release 9.7 (2025-04-09) [stable]
diff --git a/src/sort.c b/src/sort.c
index b10183b6f..7af1a2512 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -1644,7 +1644,11 @@ begfield (struct line const *line, struct keyfield const *key)
++ptr;
/* Advance PTR by SCHAR (if possible), but no further than LIM. */
- ptr = MIN (lim, ptr + schar);
+ size_t remaining_bytes = lim - ptr;
+ if (schar < remaining_bytes)
+ ptr += schar;
+ else
+ ptr = lim;
return ptr;
}
@@ -1746,7 +1750,11 @@ limfield (struct line const *line, struct keyfield const *key)
++ptr;
/* Advance PTR by ECHAR (if possible), but no further than LIM. */
- ptr = MIN (lim, ptr + echar);
+ size_t remaining_bytes = lim - ptr;
+ if (echar < remaining_bytes)
+ ptr += echar;
+ else
+ ptr = lim;
}
return ptr;

View File

@@ -0,0 +1,275 @@
{
lib,
stdenv,
fetchurl,
autoreconfHook,
buildPackages,
libiconv,
perl,
texinfo,
xz,
binlore,
coreutils,
gmpSupport ? true,
gmp,
aclSupport ? lib.meta.availableOn stdenv.hostPlatform acl,
acl,
attrSupport ? lib.meta.availableOn stdenv.hostPlatform attr,
attr,
selinuxSupport ? false,
libselinux,
libsepol,
# No openssl in default version, so openssl-induced rebuilds aren't too big.
# It makes *sum functions significantly faster.
minimal ? true,
withOpenssl ? !minimal,
openssl,
withPrefix ? false,
singleBinary ? "symlinks", # you can also pass "shebangs" or false
}:
# Note: this package is used for bootstrapping fetchurl, and thus cannot use
# fetchpatch! All mutable patches (generated by GitHub or cgit) that are needed
# here should be included directly in Nixpkgs as files.
assert aclSupport -> acl != null;
assert selinuxSupport -> libselinux != null && libsepol != null;
let
inherit (lib)
concatStringsSep
isString
optional
optionalAttrs
optionals
optionalString
;
isCross = (stdenv.hostPlatform != stdenv.buildPlatform);
in
stdenv.mkDerivation rec {
pname = "coreutils" + (optionalString (!minimal) "-full");
version = "9.7";
src = fetchurl {
url = "mirror://gnu/coreutils/coreutils-${version}.tar.xz";
hash = "sha256-6LsmrQKT+bWh/EP7QrqXDjEsZs6SwbCxZxPXUA2yUb8=";
};
patches = [
# Heap buffer overflow that's been here since coreutils 7.2 in 2009:
# https://www.openwall.com/lists/oss-security/2025/05/27/2
./CVE-2025-5278.patch
# Fixes test-float-h failure on ppc64 with C23
# https://lists.gnu.org/archive/html/bug-gnulib/2025-07/msg00021.html
# Multiple upstream commits squashed with adjustments, see header
./gnulib-float-h-tests-port-to-C23-PowerPC-GCC.patch
];
postPatch = ''
# The test tends to fail on btrfs, f2fs and maybe other unusual filesystems.
sed '2i echo Skipping dd sparse test && exit 77' -i ./tests/dd/sparse.sh
sed '2i echo Skipping du threshold test && exit 77' -i ./tests/du/threshold.sh
sed '2i echo Skipping cp reflink-auto test && exit 77' -i ./tests/cp/reflink-auto.sh
sed '2i echo Skipping cp sparse test && exit 77' -i ./tests/cp/sparse.sh
sed '2i echo Skipping env test && exit 77' -i ./tests/env/env.sh
sed '2i echo Skipping rm deep-2 test && exit 77' -i ./tests/rm/deep-2.sh
sed '2i echo Skipping du long-from-unreadable test && exit 77' -i ./tests/du/long-from-unreadable.sh
# The test tends to fail on cephfs
sed '2i echo Skipping df total-verify test && exit 77' -i ./tests/df/total-verify.sh
# Some target platforms, especially when building inside a container have
# issues with the inotify test.
sed '2i echo Skipping tail inotify dir recreate test && exit 77' -i ./tests/tail/inotify-dir-recreate.sh
# sandbox does not allow setgid
sed '2i echo Skipping chmod setgid test && exit 77' -i ./tests/chmod/setgid.sh
substituteInPlace ./tests/install/install-C.sh \
--replace 'mode3=2755' 'mode3=1755'
# Fails on systems with a rootfs. Looks like a bug in the test, see
# https://lists.gnu.org/archive/html/bug-coreutils/2019-12/msg00000.html
sed '2i print "Skipping df skip-rootfs test"; exit 77' -i ./tests/df/skip-rootfs.sh
# these tests fail in the unprivileged nix sandbox (without nix-daemon) as we break posix assumptions
for f in ./tests/chgrp/{basic.sh,recurse.sh,default-no-deref.sh,no-x.sh,posix-H.sh}; do
sed '2i echo Skipping chgrp && exit 77' -i "$f"
done
for f in gnulib-tests/{test-chown.c,test-fchownat.c,test-lchown.c}; do
echo "int main() { return 77; }" > "$f"
done
# We don't have localtime in the sandbox
for f in gnulib-tests/{test-localtime_r.c,test-localtime_r-mt.c}; do
echo "int main() { return 77; }" > "$f"
done
# These tests sometimes fail on ZFS-backed NFS filesystems
sed '2i echo "Skipping test: fails on zfs " && exit 77' -i gnulib-tests/test-file-has-acl-1.sh
sed '2i echo "Skipping test: fails on zfs " && exit 77' -i gnulib-tests/test-set-mode-acl-1.sh
sed '2i echo "Skipping test: ls/removed-directory" && exit 77' -i ./tests/ls/removed-directory.sh
# intermittent failures on builders, unknown reason
sed '2i echo Skipping du basic test && exit 77' -i ./tests/du/basic.sh
# fails when syscalls related to acl not being available, e.g. in sandboxed environment
sed '2i echo Skipping ls -al with acl test && exit 77' -i ./tests/ls/acl.sh
''
+ (optionalString (stdenv.hostPlatform.libc == "musl") (
concatStringsSep "\n" [
''
echo "int main() { return 77; }" > gnulib-tests/test-parse-datetime.c
echo "int main() { return 77; }" > gnulib-tests/test-getlogin.c
''
]
))
+ (optionalString stdenv.hostPlatform.isAarch64 ''
# Sometimes fails: https://github.com/NixOS/nixpkgs/pull/143097#issuecomment-954462584
sed '2i echo Skipping cut huge range test && exit 77' -i ./tests/cut/cut-huge-range.sh
'')
+ (optionalString stdenv.hostPlatform.isPower64
# test command fails to parse long fraction part on ppc64
# When fraction parsing is fixed, still wrong output due to fraction length mismatch
# https://debbugs.gnu.org/cgi/bugreport.cgi?bug=78985
''
sed '2i echo Skipping float sort-ing test && exit 77' -i ./tests/sort/sort-float.sh
''
);
outputs = [
"out"
"info"
];
separateDebugInfo = true;
nativeBuildInputs = [
perl
xz.bin
]
++ optionals stdenv.hostPlatform.isCygwin [
# due to patch
autoreconfHook
texinfo
];
buildInputs =
[ ]
++ optional aclSupport acl
++ optional attrSupport attr
++ optional gmpSupport gmp
++ optional withOpenssl openssl
++ optionals selinuxSupport [
libselinux
libsepol
]
# TODO(@Ericson2314): Investigate whether Darwin could benefit too
++ optional (isCross && stdenv.hostPlatform.libc != "glibc") libiconv;
hardeningDisable = [ "trivialautovarinit" ];
configureFlags = [
"--with-packager=https://nixos.org"
]
++ optional (singleBinary != false) (
"--enable-single-binary" + optionalString (isString singleBinary) "=${singleBinary}"
)
++ optional withOpenssl "--with-openssl"
++ optional stdenv.hostPlatform.isSunOS "ac_cv_func_inotify_init=no"
++ optional withPrefix "--program-prefix=g"
# the shipped configure script doesn't enable nls, but using autoreconfHook
# does so which breaks the build
++ optional stdenv.hostPlatform.isDarwin "--disable-nls"
# The VMULL-based CRC implementation produces incorrect results on musl.
# https://lists.gnu.org/archive/html/bug-coreutils/2025-02/msg00046.html
++ optional (
stdenv.hostPlatform.config == "aarch64-unknown-linux-musl"
) "utils_cv_vmull_intrinsic_exists=no"
++ optionals (isCross && stdenv.hostPlatform.libc == "glibc") [
# TODO(19b98110126fde7cbb1127af7e3fe1568eacad3d): Needed for fstatfs() I
# don't know why it is not properly detected cross building with glibc.
"fu_cv_sys_stat_statfs2_bsize=yes"
]
# /proc/uptime is available on Linux and produces accurate results even if
# the boot time is set to the epoch because the system has no RTC. We
# explicitly enable it for cases where it can't be detected automatically,
# such as when cross-compiling.
++ optional stdenv.hostPlatform.isLinux "gl_cv_have_proc_uptime=yes";
# The tests are known broken on Cygwin
# (http://article.gmane.org/gmane.comp.gnu.core-utils.bugs/19025),
# Darwin (http://article.gmane.org/gmane.comp.gnu.core-utils.bugs/19351),
# and {Open,Free}BSD.
# With non-standard storeDir: https://github.com/NixOS/nix/issues/512
doCheck =
(!isCross)
&& (stdenv.hostPlatform.libc == "glibc" || stdenv.hostPlatform.libc == "musl")
&& !stdenv.hostPlatform.isAarch32;
# Prevents attempts of running 'help2man' on cross-built binaries.
PERL = if isCross then "missing" else null;
enableParallelBuilding = true;
NIX_LDFLAGS = optionalString selinuxSupport "-lsepol";
FORCE_UNSAFE_CONFIGURE = optionalString stdenv.hostPlatform.isSunOS "1";
env.NIX_CFLAGS_COMPILE = toString (
[ ]
# Work around a bogus warning in conjunction with musl.
++ optional stdenv.hostPlatform.isMusl "-Wno-error"
++ optional stdenv.hostPlatform.isAndroid "-D__USE_FORTIFY_LEVEL=0"
);
# Works around a bug with 8.26:
# Makefile:3440: *** Recursive variable 'INSTALL' references itself (eventually). Stop.
preInstall = optionalString isCross ''
sed -i Makefile -e 's|^INSTALL =.*|INSTALL = ${buildPackages.coreutils}/bin/install -c|'
'';
postInstall =
optionalString (isCross && !minimal) ''
rm $out/share/man/man1/*
cp ${buildPackages.coreutils-full}/share/man/man1/* $out/share/man/man1
''
# du: 8.7 M locale + 0.4 M man pages
+ optionalString minimal ''
rm -r "$out/share"
'';
passthru =
{ }
// optionalAttrs (singleBinary != false) {
# everything in the single binary gets the same verdict, so we
# override _that case_ with verdicts from separate binaries.
#
# binlore only spots exec in runcon on some platforms (i.e., not
# darwin; see comment on inverse case below)
binlore.out = binlore.synthesize coreutils ''
execer can bin/{chroot,env,install,nice,nohup,runcon,sort,split,stdbuf,timeout}
execer cannot bin/{[,b2sum,base32,base64,basename,basenc,cat,chcon,chgrp,chmod,chown,cksum,comm,cp,csplit,cut,date,dd,df,dir,dircolors,dirname,du,echo,expand,expr,factor,false,fmt,fold,groups,head,hostid,id,join,kill,link,ln,logname,ls,md5sum,mkdir,mkfifo,mknod,mktemp,mv,nl,nproc,numfmt,od,paste,pathchk,pinky,pr,printenv,printf,ptx,pwd,readlink,realpath,rm,rmdir,seq,sha1sum,sha224sum,sha256sum,sha384sum,sha512sum,shred,shuf,sleep,stat,stty,sum,sync,tac,tail,tee,test,touch,tr,true,truncate,tsort,tty,uname,unexpand,uniq,unlink,uptime,users,vdir,wc,who,whoami,yes}
'';
}
// optionalAttrs (singleBinary == false) {
# binlore only spots exec in runcon on some platforms (i.e., not
# darwin; I have a note that the behavior may need selinux?).
# hard-set it so people working on macOS don't miss cases of
# runcon until ofBorg fails.
binlore.out = binlore.synthesize coreutils ''
execer can bin/runcon
'';
};
meta = with lib; {
homepage = "https://www.gnu.org/software/coreutils/";
description = "GNU Core Utilities";
longDescription = ''
The GNU Core Utilities are the basic file, shell and text manipulation
utilities of the GNU operating system. These are the core utilities which
are expected to exist on every operating system.
'';
license = licenses.gpl3Plus;
maintainers = with maintainers; [ das_j ];
platforms = with platforms; unix ++ windows;
priority = 10;
};
}

View File

@@ -0,0 +1,230 @@
Applies the following incremental gnulib commits:
- 55a366a06fbd98bf13adc531579e3513cee97a32
- 65ed9d3b24ad09fd61d326c83e7f1b05f6e9d65f
- ce8e9de0bf34bc63dffc67ab384334c509175f64
- 6164b4cb0887b5331a4e64449107decd37d32735
With adjustments specific to the structure & differences in coreutils:
- gnulib code is split across lib and gnulib-tests
- A Makefile.in is used for the test flags instead of the fancy automake modules
in the upstream gnulib project, so we add -lm to the float test there.
Surrounding texts in this file are slightly different in every project.
---
diff '--color=auto' -ruN a/gnulib-tests/Makefile.in b/gnulib-tests/Makefile.in
--- a/gnulib-tests/Makefile.in 2025-04-09 10:05:54.000000000 +0000
+++ b/gnulib-tests/Makefile.in 2025-07-09 10:00:23.767927263 +0000
@@ -1496,7 +1496,7 @@
$(am__DEPENDENCIES_1)
test_float_h_SOURCES = test-float-h.c
test_float_h_OBJECTS = test-float-h.$(OBJEXT)
-test_float_h_LDADD = $(LDADD)
+test_float_h_LDADD = $(LDADD) -lm
test_float_h_DEPENDENCIES = libtests.a ../lib/libcoreutils.a \
libtests.a ../lib/libcoreutils.a libtests.a \
$(am__DEPENDENCIES_1)
diff '--color=auto' -ruN a/gnulib-tests/test-float-h.c b/gnulib-tests/test-float-h.c
--- a/gnulib-tests/test-float-h.c 2025-01-01 09:32:30.000000000 +0000
+++ b/gnulib-tests/test-float-h.c 2025-07-09 10:00:13.837937094 +0000
@@ -101,6 +101,8 @@
/* ------------------------------------------------------------------------- */
+#include <math.h>
+
#include "fpucw.h"
#include "isnanf-nolibm.h"
#include "isnand-nolibm.h"
@@ -396,6 +398,44 @@
/* -------------------- Check macros for 'long double' -------------------- */
+static int
+test_isfinitel (long double volatile x)
+{
+ if (x != x)
+ return 0;
+ long double volatile zero = x * 0;
+ return zero == 0;
+}
+
+/* Return X after normalization. This makes a difference on platforms
+ where long double can represent unnormalized values. For example,
+ suppose x = 1 + 2**-106 on PowerPC with IBM long double where
+ FLT_RADIX = 2, LDBL_MANT_DIG = 106, and LDBL_EPSILON = 2**-105.
+ Then 1 < x < 1 + LDBL_EPSILON, and normalize_long_double (x) returns 1. */
+static long double
+normalize_long_double (long double volatile x)
+{
+ if (FLT_RADIX == 2 && test_isfinitel (x))
+ {
+ int xexp;
+ long double volatile
+ frac = frexpl (x, &xexp),
+ significand = frac * pow2l (LDBL_MANT_DIG),
+ normalized_significand = truncl (significand),
+ normalized_x = normalized_significand * pow2l (xexp - LDBL_MANT_DIG);
+
+ /* The test_isfinitel defends against PowerPC with IBM long double,
+ which fritzes out near LDBL_MAX. */
+ if (test_isfinitel (normalized_x))
+ x = normalized_x;
+ }
+ else
+ {
+ /* Hope that X is already normalized. */
+ }
+ return x;
+}
+
static void
test_long_double (void)
{
@@ -455,7 +495,7 @@
for (n = 0; n <= 2 * LDBL_MANT_DIG; n++)
{
volatile long double half_n = pow2l (- n); /* 2^-n */
- volatile long double x = me - half_n;
+ volatile long double x = normalize_long_double (me - half_n);
if (x < me)
ASSERT (x <= 1.0L);
}
@@ -483,8 +523,12 @@
ASSERT (!LDBL_IS_IEC_60559);
#endif
+ printf("LDBL_NORM_MAX: %LF\n", LDBL_NORM_MAX);
+ printf("LDBL_MAX: %LF\n", LDBL_MAX);
+ printf("normalize_long_double(LDBL_MAX): %LF\n", normalize_long_double(LDBL_MAX));
+
/* Check the value of LDBL_NORM_MAX. */
- ASSERT (LDBL_NORM_MAX == LDBL_MAX);
+ ASSERT (LDBL_NORM_MAX == normalize_long_double (LDBL_MAX));
/* Check the value of LDBL_SNAN. */
ASSERT (isnanl (LDBL_SNAN));
diff '--color=auto' -ruN a/lib/float.c b/lib/float.c
--- a/lib/float.c 2025-01-01 09:32:29.000000000 +0000
+++ b/lib/float.c 2025-07-09 10:00:13.837937094 +0000
@@ -23,7 +23,7 @@
#if GNULIB_defined_long_double_union
# if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__
const union gl_long_double_union gl_LDBL_MAX =
- { { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL } };
+ { { DBL_MAX, DBL_MAX / 0x1p53 } };
# elif defined __i386__
const union gl_long_double_union gl_LDBL_MAX =
{ { 0xFFFFFFFF, 0xFFFFFFFF, 32766 } };
diff '--color=auto' -ruN a/lib/float.in.h b/lib/float.in.h
--- a/lib/float.in.h 2025-01-01 09:32:29.000000000 +0000
+++ b/lib/float.in.h 2025-07-09 10:00:13.837937094 +0000
@@ -113,44 +113,38 @@
# define LDBL_MAX_10_EXP 4932
#endif
-/* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are
- wrong.
- On Linux/PowerPC with gcc 4.4, the value of LDBL_MAX is wrong. */
-#if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__
+/* On PowerPC with gcc 15 when using __ibm128 long double, the value of
+ LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX, and LDBL_NORM_MAX are wrong. */
+#if ((defined _ARCH_PPC || defined _POWER) && LDBL_MANT_DIG == 106 \
+ && defined __GNUC__)
# undef LDBL_MIN_EXP
# define LDBL_MIN_EXP DBL_MIN_EXP
# undef LDBL_MIN_10_EXP
# define LDBL_MIN_10_EXP DBL_MIN_10_EXP
# undef LDBL_MIN
# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */
-#endif
-#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__
# undef LDBL_MAX
-/* LDBL_MAX is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xFFFFFFFF }.
- It is not easy to define:
- #define LDBL_MAX 1.79769313486231580793728971405302307166e308L
- is too small, whereas
- #define LDBL_MAX 1.79769313486231580793728971405302307167e308L
- is too large. Apparently a bug in GCC decimal-to-binary conversion.
- Also, I can't get values larger than
- #define LDBL63 ((long double) (1ULL << 63))
- #define LDBL882 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63)
- #define LDBL945 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63)
- #define LDBL1008 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63)
- #define LDBL_MAX (LDBL1008 * 65535.0L + LDBL945 * (long double) 9223372036821221375ULL + LDBL882 * (long double) 4611686018427387904ULL)
- which is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xF8000000 }.
- So, define it like this through a reference to an external variable
+/* LDBL_MAX is 2**1024 - 2**918, represented as: { 0x7FEFFFFF, 0xFFFFFFFF,
+ 0x7C9FFFFF, 0xFFFFFFFF }.
+
+ Do not write it as a constant expression, as GCC would likely treat
+ that as infinity due to the vagaries of this platform's funky arithmetic.
+ Instead, define it through a reference to an external variable.
+ Like the following, but using a union to avoid type mismatches:
- const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL };
+ const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / 0x1p53 };
extern const long double LDBL_MAX;
- or through a pointer cast
+ The following alternative would not work as well when GCC is optimizing:
+
+ #define LDBL_MAX (*(long double const *) (double[])
+ { DBL_MAX, DBL_MAX / 0x1p53 })
- #define LDBL_MAX \
- (*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL })
+ The following alternative would require GCC 6 or later:
- Unfortunately, this is not a constant expression, and the latter expression
- does not work well when GCC is optimizing.. */
+ #define LDBL_MAX __builtin_pack_longdouble (DBL_MAX, DBL_MAX / 0x1p53)
+
+ Unfortunately none of the alternatives are constant expressions. */
# if !GNULIB_defined_long_double_union
union gl_long_double_union
{
@@ -161,6 +155,8 @@
# endif
extern const union gl_long_double_union gl_LDBL_MAX;
# define LDBL_MAX (gl_LDBL_MAX.ld)
+# undef LDBL_NORM_MAX
+# define LDBL_NORM_MAX LDBL_MAX
#endif
/* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong.
@@ -181,6 +177,21 @@
# endif
#endif
+/* On PowerPC platforms, 'long double' has a double-double representation.
+ Up to ISO C 17, this was outside the scope of ISO C because it can represent
+ numbers with mantissas of the form 1.<52 bits><many zeroes><52 bits>, such as
+ 1.0L + 4.94065645841246544176568792868221e-324L = 1 + 2^-1074; see
+ ISO C 17 § 5.2.4.2.2.(3).
+ In ISO C 23, wording has been included that makes this 'long double'
+ representation compliant; see ISO C 23 § 5.2.5.3.3.(8)-(9). In this setting,
+ numbers with mantissas of the form 1.<52 bits><many zeroes><52 bits> are
+ called "unnormalized". And since LDBL_EPSILON must be normalized (per
+ ISO C 23 § 5.2.5.3.3.(33)), it must be 2^-105. */
+#if defined __powerpc__ && LDBL_MANT_DIG == 106
+# undef LDBL_EPSILON
+# define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */
+#endif
+
/* ============================ ISO C11 support ============================ */
/* 'float' properties */
@@ -309,7 +320,11 @@
# endif
#endif
#ifndef LDBL_NORM_MAX
-# define LDBL_NORM_MAX LDBL_MAX
+# ifdef __LDBL_NORM_MAX__
+# define LDBL_NORM_MAX __LDBL_NORM_MAX__
+# else
+# define LDBL_NORM_MAX LDBL_MAX
+# endif
#endif
#ifndef LDBL_SNAN
/* For sh, beware of <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111814>. */