From a3f4ef7adf5b26dc9a2c0930d5c72b2d9ea994f0 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Fri, 15 Jan 2021 15:20:16 +0000 Subject: [PATCH] libast: fix detection of long double NaN/INF signatures src/lib/libast/features/float: - libast attempts to determine the binary representation of Inf and NaN to use as a fall-back code path for systems that do not support fpclassify(). The libast feature detection did not get consistent signatures between builds. To fix this, zero the memory before determining the signature. src/lib/libast/sfio/sfcvt.c: - The fall-back code path is broken because there are multiple representations for NaN - the important thing is to check the exponent and for a non-zero significand. The trailing bits can be random or left over from interim operations. For that reason, to ensure we never end up using the fall-back code path, explicitly generate a compile error if we end up there. Based on a patch from @citrus-it: https://github.com/citrus-it/ast/commit/8bf59a9a8fb9b0b00316f0c46c145b7a6c0dcc91 but uses POSIX memset(3) instead of deprecated bzero(3). --- src/lib/libast/features/float | 3 +++ src/lib/libast/sfio/sfcvt.c | 1 + 2 files changed, 4 insertions(+) diff --git a/src/lib/libast/features/float b/src/lib/libast/features/float index cadf8f201..d927bc167 100644 --- a/src/lib/libast/features/float +++ b/src/lib/libast/features/float @@ -993,6 +993,7 @@ tst - -DSCAN=1 - -lm -DSTRTO=1 - -DMAC=1 - -DDIV=1 - -DEXP=1 - -DADD=1 - -DMPY=1 #include #include #include + #include #if _hdr_float #include #endif @@ -1094,6 +1095,7 @@ tst - -DSCAN=1 - -lm -DSTRTO=1 - -DMAC=1 - -DDIV=1 - -DEXP=1 - -DADD=1 - -DMPY=1 char* e; #endif + memset(&f, '\0', sizeof(f)); #if SCAN if (sscanf(NAN, "%Lg", &f) != 1) return 1; @@ -1103,6 +1105,7 @@ tst - -DSCAN=1 - -lm -DSTRTO=1 - -DMAC=1 - -DDIV=1 - -DEXP=1 - -DADD=1 - -DMPY=1 return 1; #endif list("ldbl", "nan", &f, sizeof(f)); + memset(&f, '\0', sizeof(f)); #if SCAN if (sscanf(INF, "%Lg", &f) != 1) return 1; diff --git a/src/lib/libast/sfio/sfcvt.c b/src/lib/libast/sfio/sfcvt.c index a83b8ef89..8063a5f42 100644 --- a/src/lib/libast/sfio/sfcvt.c +++ b/src/lib/libast/sfio/sfcvt.c @@ -44,6 +44,7 @@ static char *Zero = "0"; #define isnan(n) (fpclassify(n)==FP_NAN) #define isnanl(n) (fpclassify(n)==FP_NAN) #else +#error "This is an invalid test for NaN" #define isnan(n) (memcmp((void*)&n,(void*)&_Sfdnan,sizeof(n))==0) #define isnanl(n) (memcmp((void*)&n,(void*)&_Sflnan,sizeof(n))==0) #endif