Branch
Hash :
fc59330b
Author :
Date :
2025-05-07T09:47:49
Fix "make sc_check_config_h_reminder" failure. * Makefile (config_h_MACROS2): Add _GL_ATTRIBUTE_DEALLOC_FREE, _GL_ATTRIBUTE_NONNULL_IF_NONZERO, _GL_ATTRIBUTE_REPRODUCIBLE, _GL_ATTRIBUTE_UNSEQUENCED, _GL_ATTRIBUTE_CAPABILITY_TYPE, _GL_ATTRIBUTE_ACQUIRE_CAPABILITY, _GL_ATTRIBUTE_RELEASE_CAPABILITY. (exclude_file_name_regexp--sc_check_config_h_reminder): New variable. (sc_check_config_h_reminder): Use it. * lib/areadlink.h: Add <config.h> reminder. * lib/crc.h: Likewise. * lib/crc-x86_64.h: Likewise. * lib/diffseq.h: Likewise. * lib/gl_sublist.h: Likewise. * lib/signed-nan.h: Likewise. * lib/signed-snan.h: Likewise. * lib/snan.h: Likewise. * lib/unicase/special-casing.in.h: Likewise.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
/* Macros for signalling not-a-number.
Copyright (C) 2007-2025 Free Software Foundation, Inc.
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _SNAN_H
#define _SNAN_H
/* This file uses _GL_UNUSED. */
#if !_GL_CONFIG_H_INCLUDED
#error "Please include config.h first."
#endif
#include <float.h>
#include <limits.h>
#include <math.h>
#include "nan.h"
#ifdef __cplusplus
extern "C" {
#endif
/* The bit that distinguishes a quiet NaN from a signalling NaN is, according to
<https://en.wikipedia.org/wiki/NaN#Encoding>, the most significant bit of the
mantissa field.
According to <https://en.wikipedia.org/wiki/IEEE_754#Formats>, this is the
next bit, right below the bit 0 of the exponent.
This bit is
* == 0 to indicate a quiet NaN or Infinity,
== 1 to indicate a signalling NaN,
on these CPUs: hppa, mips (*), sh4.
* == 1 to indicate a quiet NaN,
== 0 to indicate a signalling NaN or Infinity,
on all other CPUs.
On these platforms, additionally a signalling NaN must have some other
mantissa bit == 1, because when all exponent bits are == 1 and all
mantissa bits are == 0, the number denotes ±Infinity.
This NaN encoding is specified by IEEE 754-2008 § 6.2.1.
(*) On mips CPUs, it depends on the CPU model. The classical behaviour is
as indicated above. On some newer models, it's like on the other CPUs.
On some (but not all!) models this meta-info can be determined from two
special CPU registers: If the "Floating Point Implementation Register" (fir)
bit 23, also known as Has2008 bit, is set, the "Floating Point Control and
Status Register" (fcsr) bit 18, also known as the NAN2008 bit, has the value
- 0 for the classical behaviour,
- 1 for like on the other CPUs.
Both of these bits are read-only.
This module has determined the behaviour at configure time and defines the
C macros MIPS_NAN2008_FLOAT, MIPS_NAN2008_DOUBLE, MIPS_NAN2008_LONG_DOUBLE
accordingly. */
/* 'float' = IEEE 754 single-precision
<https://en.wikipedia.org/wiki/Single-precision_floating-point_format> */
#define NWORDS \
((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
typedef union { float value; unsigned int word[NWORDS]; } memory_float;
#if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
# define HAVE_SNANF 1
_GL_UNUSED static memory_float
construct_memory_SNaNf (float quiet_value)
{
memory_float m;
m.value = quiet_value;
/* Turn the quiet NaN into a signalling NaN. */
#if FLT_EXPBIT0_BIT > 0
m.word[FLT_EXPBIT0_WORD] ^= (unsigned int) 1 << (FLT_EXPBIT0_BIT - 1);
#else
m.word[FLT_EXPBIT0_WORD + (FLT_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
#endif
/* Set some arbitrary mantissa bit. */
if (FLT_EXPBIT0_WORD < NWORDS / 2) /* NWORDS > 1 and big endian */
m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT;
else /* NWORDS == 1 or little endian */
m.word[0] |= (unsigned int) 1;
return m;
}
/* Returns a signalling 'float' NaN in memory. */
_GL_UNUSED static memory_float
memory_SNaNf ()
{
return construct_memory_SNaNf (NaNf ());
}
_GL_UNUSED static float
construct_SNaNf (float quiet_value)
{
return construct_memory_SNaNf (quiet_value).value;
}
/* Returns a signalling 'float' NaN.
Note: On 32-bit x86 processors, as well as on x86_64 processors with
CC="gcc -mfpmath=387", this function may return a quiet NaN instead.
Use memory_SNaNf() if you need to avoid this. See
<https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
for details. */
_GL_UNUSED static float
SNaNf ()
{
return memory_SNaNf ().value;
}
#endif
#undef NWORDS
/* 'double' = IEEE 754 double-precision
<https://en.wikipedia.org/wiki/Double-precision_floating-point_format> */
#define NWORDS \
((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
typedef union { double value; unsigned int word[NWORDS]; } memory_double;
#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
# define HAVE_SNAND 1
_GL_UNUSED static memory_double
construct_memory_SNaNd (double quiet_value)
{
memory_double m;
m.value = quiet_value;
/* Turn the quiet NaN into a signalling NaN. */
#if DBL_EXPBIT0_BIT > 0
m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1);
#else
m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
#endif
/* Set some arbitrary mantissa bit. */
m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
|= (unsigned int) 1 << DBL_EXPBIT0_BIT;
return m;
}
/* Returns a signalling 'double' NaN in memory. */
_GL_UNUSED static memory_double
memory_SNaNd ()
{
return construct_memory_SNaNd (NaNd ());
}
_GL_UNUSED static double
construct_SNaNd (double quiet_value)
{
return construct_memory_SNaNd (quiet_value).value;
}
/* Returns a signalling 'double' NaN.
Note: On 32-bit x86 processors, as well as on x86_64 processors with
CC="gcc -mfpmath=387", this function may return a quiet NaN instead.
Use memory_SNaNf() if you need to avoid this. See
<https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
for details. */
_GL_UNUSED static double
SNaNd ()
{
return memory_SNaNd ().value;
}
#endif
#undef NWORDS
/* 'long double' =
* if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE:
IEEE 754 double-precision
<https://en.wikipedia.org/wiki/Double-precision_floating-point_format>
* Otherwise:
- On i386, x86_64, ia64:
80-bits extended-precision
<https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format>
- On alpha, arm64, loongarch64, mips64, riscv64, s390x, sparc64:
IEEE 754 quadruple-precision
<https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#IEEE_754_quadruple-precision_binary_floating-point_format:_binary128>
- On powerpc, powerpc64, powerpc64le:
2x64-bits double-double
<https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic>
- On m68k:
80-bits extended-precision, padded to 96 bits, with non-IEEE exponent
*/
#define NWORDS \
((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
typedef union { long double value; unsigned int word[NWORDS]; }
memory_long_double;
#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
# define HAVE_SNANL 1
_GL_UNUSED static memory_long_double
construct_memory_SNaNl (long double quiet_value)
{
memory_long_double m;
m.value = quiet_value;
#if defined __powerpc__ && LDBL_MANT_DIG == 106
/* This is PowerPC "double double", a pair of two doubles. Inf and NaN are
represented as the corresponding 64-bit IEEE values in the first double;
the second is ignored. Manipulate only the first double. */
#define HNWORDS \
((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
#else
#define HNWORDS NWORDS
#endif
/* Turn the quiet NaN into a signalling NaN. */
#if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
/* In this representation, the leading 1 of the mantissa is explicitly
stored. */
#if LDBL_EXPBIT0_BIT > 1
m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 2);
#else
m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)]
^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 2);
#endif
#elif (defined __m68k__ && LDBL_MANT_DIG == 64) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
/* In this representation, there is a 16-bits gap between the exponent and
the mantissa, and the leading 1 of the mantissa is explicitly stored. */
m.word[LDBL_EXPBIT0_WORD + 1]
^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 2);
#else
/* In this representation, the leading 1 of the mantissa is implicit. */
#if LDBL_EXPBIT0_BIT > 0
m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1);
#else
m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)]
^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
#endif
#endif
/* Set some arbitrary mantissa bit. */
m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)]
|= (unsigned int) 1 << LDBL_EXPBIT0_BIT;
#undef HNWORDS
return m;
}
/* Returns a signalling 'long double' NaN in memory. */
_GL_UNUSED static memory_long_double
memory_SNaNl ()
{
return construct_memory_SNaNl (NaNl ());
}
_GL_UNUSED static long double
construct_SNaNl (long double quiet_value)
{
return construct_memory_SNaNl (quiet_value).value;
}
/* Returns a signalling 'long double' NaN.
Note: On 32-bit x86 processors, as well as on x86_64 processors with
CC="gcc -mfpmath=387", if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE is 1, this
function may return a quiet NaN instead. Use memory_SNaNf() if you
need to avoid this. See
<https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
for details. */
_GL_UNUSED static long double
SNaNl ()
{
return memory_SNaNl ().value;
}
#endif
#undef NWORDS
#ifdef __cplusplus
}
#endif
#endif /* _SNAN_H */