1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

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:
8bf59a9a8f
but uses POSIX memset(3) instead of deprecated bzero(3).
This commit is contained in:
Martijn Dekker 2021-01-15 15:20:16 +00:00
parent 3aa01a95ee
commit a3f4ef7adf
2 changed files with 4 additions and 0 deletions

View file

@ -993,6 +993,7 @@ tst - -DSCAN=1 - -lm -DSTRTO=1 - -DMAC=1 - -DDIV=1 - -DEXP=1 - -DADD=1 - -DMPY=1
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#if _hdr_float
#include <float.h>
#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;

View file

@ -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