]> git.ipfire.org Git - thirdparty/glibc.git/blame - math/test-snan.c
New <math.h> macro named issignaling to check for a signaling NaN (sNaN).
[thirdparty/glibc.git] / math / test-snan.c
CommitLineData
57267616 1/* Test signaling NaNs in issignaling, isnan, isinf, and similar functions.
568035b7 2 Copyright (C) 2008-2013 Free Software Foundation, Inc.
5f7aead5
UD
3 This file is part of the GNU C Library.
4 Contributed by Andreas Jaeger <aj@suse.de>, 2005.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
5f7aead5 19
d643bac1 20#define _GNU_SOURCE 1
5f7aead5
UD
21#include <stdio.h>
22#include <stdlib.h>
23#include <sys/time.h>
24#include <string.h>
25#include <math.h>
26#include <float.h>
27#include <fenv.h>
28#include <signal.h>
29#include <setjmp.h>
30#include <errno.h>
31
5aa4a1a1
TS
32#include <math-tests.h>
33
34
5f7aead5
UD
35int dest_offset;
36char *dest_address;
37double value = 123.456;
38double zero = 0.0;
39
5f7aead5
UD
40static sigjmp_buf sigfpe_buf;
41
5f7aead5
UD
42typedef long double ldouble;
43
5f7aead5
UD
44
45void
46myFPsighandler(int signal,
47 siginfo_t *info,
48 void *context)
49{
50 siglongjmp(sigfpe_buf, 0);
51}
52
53int
54set_sigaction_FP(void)
55{
56 struct sigaction sa;
57 /* register RT signal handler via sigaction */
58 sa.sa_flags = SA_SIGINFO;
59 sa.sa_sigaction = &myFPsighandler;
60 sigemptyset(&sa.sa_mask);
61 sigaction(SIGFPE, &sa, NULL);
62
63 return 0;
64}
65
66int
67remove_sigaction_FP(void)
68{
69 struct sigaction sa;
70 /* restore default RT signal handler via sigaction */
71 sa.sa_flags = SA_SIGINFO;
72 sa.sa_handler = SIG_DFL;
73 sigemptyset(&sa.sa_mask);
74 sigaction(SIGFPE, &sa, NULL);
75
76 return 0;
77}
78
79static int errors = 0;
80
81static void
82check (const char *testname, int result)
83{
84 if (!result) {
85 printf ("Failure: %s\n", testname);
86 errors++;
87 }
88}
89
777b0332 90#define TEST_FUNC(NAME, FLOAT, SUFFIX) \
5f7aead5
UD
91static void \
92NAME (void) \
93{ \
94 /* Variables are declared volatile to forbid some compiler \
95 optimizations. */ \
777b0332
TS
96 volatile FLOAT Inf_var, qNaN_var, zero_var, one_var; \
97 /* A sNaN is only guaranteed to be representable in variables with */ \
98 /* static (or thread-local) storage duration. */ \
99 static volatile FLOAT sNaN_var = __builtin_nans ## SUFFIX (""); \
6cbec759 100 static volatile FLOAT minus_sNaN_var = -__builtin_nans ## SUFFIX (""); \
5f7aead5
UD
101 fenv_t saved_fenv; \
102 \
103 zero_var = 0.0; \
104 one_var = 1.0; \
777b0332 105 qNaN_var = __builtin_nan ## SUFFIX (""); \
5f7aead5
UD
106 Inf_var = one_var / zero_var; \
107 \
108 (void) &zero_var; \
109 (void) &one_var; \
67e971f1
TS
110 (void) &qNaN_var; \
111 (void) &sNaN_var; \
6cbec759 112 (void) &minus_sNaN_var; \
5f7aead5
UD
113 (void) &Inf_var; \
114 \
115 set_sigaction_FP (); \
116 fegetenv(&saved_fenv); \
117 \
118 feclearexcept(FE_ALL_EXCEPT); \
119 feenableexcept (FE_ALL_EXCEPT); \
57267616
TS
120 if (sigsetjmp(sigfpe_buf, 0)) \
121 { \
122 printf (#FLOAT " issignaling (qNaN) raised SIGFPE\n"); \
123 errors++; \
124 } else { \
125 check (#FLOAT " issignaling (qNaN)", !issignaling (qNaN_var)); \
126 } \
127 \
128 feclearexcept(FE_ALL_EXCEPT); \
129 feenableexcept (FE_ALL_EXCEPT); \
130 if (sigsetjmp(sigfpe_buf, 0)) \
131 { \
132 printf (#FLOAT " issignaling (-qNaN) raised SIGFPE\n"); \
133 errors++; \
134 } else { \
135 check (#FLOAT " issignaling (-qNaN)", !issignaling (-qNaN_var)); \
136 } \
137 \
138 feclearexcept(FE_ALL_EXCEPT); \
139 feenableexcept (FE_ALL_EXCEPT); \
140 if (sigsetjmp(sigfpe_buf, 0)) \
141 { \
142 printf (#FLOAT " issignaling (sNaN) raised SIGFPE\n"); \
143 errors++; \
144 } else { \
145 check (#FLOAT " issignaling (sNaN)", \
146 SNAN_TESTS (FLOAT) ? issignaling (sNaN_var) : 1); \
147 } \
148 \
149 feclearexcept(FE_ALL_EXCEPT); \
150 feenableexcept (FE_ALL_EXCEPT); \
151 if (sigsetjmp(sigfpe_buf, 0)) \
152 { \
153 printf (#FLOAT " issignaling (-sNaN) raised SIGFPE\n"); \
154 errors++; \
155 } else { \
156 check (#FLOAT " issignaling (-sNaN)", \
157 SNAN_TESTS (FLOAT) ? issignaling (minus_sNaN_var) : 1); \
158 } \
159 \
160 feclearexcept(FE_ALL_EXCEPT); \
161 feenableexcept (FE_ALL_EXCEPT); \
5f7aead5
UD
162 if (sigsetjmp(sigfpe_buf, 0)) \
163 { \
67e971f1 164 printf (#FLOAT " isnan (qNaN) raised SIGFPE\n"); \
5f7aead5
UD
165 errors++; \
166 } else { \
67e971f1 167 check (#FLOAT " isnan (qNaN)", isnan (qNaN_var)); \
5f7aead5
UD
168 } \
169 \
170 feclearexcept(FE_ALL_EXCEPT); \
171 feenableexcept (FE_ALL_EXCEPT); \
172 if (sigsetjmp(sigfpe_buf, 0)) \
173 { \
67e971f1 174 printf (#FLOAT " isnan (-qNaN) raised SIGFPE\n"); \
5f7aead5
UD
175 errors++; \
176 } else { \
67e971f1 177 check (#FLOAT " isnan (-qNaN)", isnan (-qNaN_var)); \
5f7aead5
UD
178 } \
179 \
180 feclearexcept(FE_ALL_EXCEPT); \
181 feenableexcept (FE_ALL_EXCEPT); \
182 if (sigsetjmp(sigfpe_buf, 0)) \
183 { \
67e971f1 184 printf (#FLOAT " isnan (sNaN) raised SIGFPE\n"); \
5f7aead5
UD
185 errors++; \
186 } else { \
5aa4a1a1
TS
187 check (#FLOAT " isnan (sNaN)", \
188 SNAN_TESTS (FLOAT) ? isnan (sNaN_var) : 1); \
5f7aead5
UD
189 } \
190 \
191 feclearexcept(FE_ALL_EXCEPT); \
192 feenableexcept (FE_ALL_EXCEPT); \
193 if (sigsetjmp(sigfpe_buf, 0)) \
194 { \
67e971f1 195 printf (#FLOAT " isnan (-sNaN) raised SIGFPE\n"); \
5f7aead5
UD
196 errors++; \
197 } else { \
5aa4a1a1
TS
198 check (#FLOAT " isnan (-sNaN)", \
199 SNAN_TESTS (FLOAT) ? isnan (minus_sNaN_var) : 1); \
5f7aead5
UD
200 } \
201 \
202 feclearexcept(FE_ALL_EXCEPT); \
203 feenableexcept (FE_ALL_EXCEPT); \
204 if (sigsetjmp(sigfpe_buf, 0)) \
205 { \
67e971f1 206 printf (#FLOAT " isinf (qNaN) raised SIGFPE\n"); \
5f7aead5
UD
207 errors++; \
208 } else { \
67e971f1 209 check (#FLOAT " isinf (qNaN)", !isinf (qNaN_var)); \
5f7aead5
UD
210 } \
211 \
212 feclearexcept(FE_ALL_EXCEPT); \
213 feenableexcept (FE_ALL_EXCEPT); \
214 if (sigsetjmp(sigfpe_buf, 0)) \
215 { \
67e971f1 216 printf (#FLOAT " isinf (-qNaN) raised SIGFPE\n"); \
5f7aead5
UD
217 errors++; \
218 } else { \
67e971f1 219 check (#FLOAT " isinf (-qNaN)", !isinf (-qNaN_var)); \
5f7aead5
UD
220 } \
221 \
222 feclearexcept(FE_ALL_EXCEPT); \
223 feenableexcept (FE_ALL_EXCEPT); \
224 if (sigsetjmp(sigfpe_buf, 0)) \
225 { \
67e971f1 226 printf (#FLOAT " isinf (sNaN) raised SIGFPE\n"); \
5f7aead5
UD
227 errors++; \
228 } else { \
5aa4a1a1
TS
229 check (#FLOAT " isinf (sNaN)", \
230 SNAN_TESTS (FLOAT) ? !isinf (sNaN_var) : 1); \
5f7aead5
UD
231 } \
232 \
233 feclearexcept(FE_ALL_EXCEPT); \
234 feenableexcept (FE_ALL_EXCEPT); \
235 if (sigsetjmp(sigfpe_buf, 0)) \
236 { \
67e971f1 237 printf (#FLOAT " isinf (-sNaN) raised SIGFPE\n"); \
5f7aead5
UD
238 errors++; \
239 } else { \
5aa4a1a1
TS
240 check (#FLOAT " isinf (-sNaN)", \
241 SNAN_TESTS (FLOAT) ? !isinf (minus_sNaN_var) : 1); \
5f7aead5
UD
242 } \
243 \
244 feclearexcept(FE_ALL_EXCEPT); \
245 feenableexcept (FE_ALL_EXCEPT); \
246 if (sigsetjmp(sigfpe_buf, 0)) \
247 { \
67e971f1 248 printf (#FLOAT " isfinite (qNaN) raised SIGFPE\n"); \
5f7aead5
UD
249 errors++; \
250 } else { \
67e971f1 251 check (#FLOAT " isfinite (qNaN)", !isfinite (qNaN_var)); \
5f7aead5
UD
252 } \
253 \
254 feclearexcept(FE_ALL_EXCEPT); \
255 feenableexcept (FE_ALL_EXCEPT); \
256 if (sigsetjmp(sigfpe_buf, 0)) \
257 { \
67e971f1 258 printf (#FLOAT " isfinite (-qNaN) raised SIGFPE\n"); \
5f7aead5
UD
259 errors++; \
260 } else { \
67e971f1 261 check (#FLOAT " isfinite (-qNaN)", !isfinite (-qNaN_var)); \
5f7aead5
UD
262 } \
263 \
264 feclearexcept(FE_ALL_EXCEPT); \
265 feenableexcept (FE_ALL_EXCEPT); \
266 if (sigsetjmp(sigfpe_buf, 0)) \
267 { \
67e971f1 268 printf (#FLOAT " isfinite (sNaN) raised SIGFPE\n"); \
5f7aead5
UD
269 errors++; \
270 } else { \
5aa4a1a1
TS
271 check (#FLOAT " isfinite (sNaN)", \
272 SNAN_TESTS (FLOAT) ? !isfinite (sNaN_var) : 1); \
5f7aead5
UD
273 } \
274 \
275 feclearexcept(FE_ALL_EXCEPT); \
276 feenableexcept (FE_ALL_EXCEPT); \
277 if (sigsetjmp(sigfpe_buf, 0)) \
278 { \
67e971f1 279 printf (#FLOAT " isfinite (-sNaN) raised SIGFPE\n"); \
5f7aead5
UD
280 errors++; \
281 } else { \
5aa4a1a1
TS
282 check (#FLOAT " isfinite (-sNaN)", \
283 SNAN_TESTS (FLOAT) ? !isfinite (minus_sNaN_var) : 1); \
5f7aead5
UD
284 } \
285 \
286 feclearexcept(FE_ALL_EXCEPT); \
287 feenableexcept (FE_ALL_EXCEPT); \
288 if (sigsetjmp(sigfpe_buf, 0)) \
289 { \
67e971f1 290 printf (#FLOAT " isnormal (qNaN) raised SIGFPE\n"); \
5f7aead5
UD
291 errors++; \
292 } else { \
67e971f1 293 check (#FLOAT " isnormal (qNaN)", !isnormal (qNaN_var)); \
5f7aead5
UD
294 } \
295 \
296 feclearexcept(FE_ALL_EXCEPT); \
297 feenableexcept (FE_ALL_EXCEPT); \
298 if (sigsetjmp(sigfpe_buf, 0)) \
299 { \
67e971f1 300 printf (#FLOAT " isnormal (-qNaN) raised SIGFPE\n"); \
5f7aead5
UD
301 errors++; \
302 } else { \
67e971f1 303 check (#FLOAT " isnormal (-qNaN)", !isnormal (-qNaN_var)); \
5f7aead5
UD
304 } \
305 \
306 feclearexcept(FE_ALL_EXCEPT); \
307 feenableexcept (FE_ALL_EXCEPT); \
308 if (sigsetjmp(sigfpe_buf, 0)) \
309 { \
67e971f1 310 printf (#FLOAT " isnormal (sNaN) isnormal SIGFPE\n"); \
5f7aead5
UD
311 errors++; \
312 } else { \
5aa4a1a1
TS
313 check (#FLOAT " isnormal (sNaN)", \
314 SNAN_TESTS (FLOAT) ? !isnormal (sNaN_var) : 1); \
5f7aead5
UD
315 } \
316 \
317 feclearexcept(FE_ALL_EXCEPT); \
318 feenableexcept (FE_ALL_EXCEPT); \
319 if (sigsetjmp(sigfpe_buf, 0)) \
320 { \
67e971f1 321 printf (#FLOAT " isnormal (-sNaN) raised SIGFPE\n"); \
5f7aead5
UD
322 errors++; \
323 } else { \
5aa4a1a1
TS
324 check (#FLOAT " isnormal (-sNaN)", \
325 SNAN_TESTS (FLOAT) ? !isnormal (minus_sNaN_var) : 1); \
5f7aead5
UD
326 } \
327 \
328 feclearexcept(FE_ALL_EXCEPT); \
329 feenableexcept (FE_ALL_EXCEPT); \
330 if (sigsetjmp(sigfpe_buf, 0)) \
331 { \
67e971f1 332 printf (#FLOAT " fpclassify (qNaN) raised SIGFPE\n"); \
5f7aead5
UD
333 errors++; \
334 } else { \
67e971f1 335 check (#FLOAT " fpclassify (qNaN)", (fpclassify (qNaN_var)==FP_NAN)); \
5f7aead5
UD
336 } \
337 \
338 feclearexcept(FE_ALL_EXCEPT); \
339 feenableexcept (FE_ALL_EXCEPT); \
340 if (sigsetjmp(sigfpe_buf, 0)) \
341 { \
67e971f1 342 printf (#FLOAT " fpclassify (-qNaN) raised SIGFPE\n"); \
5f7aead5
UD
343 errors++; \
344 } else { \
67e971f1 345 check (#FLOAT " fpclassify (-qNaN)", (fpclassify (-qNaN_var)==FP_NAN)); \
5f7aead5
UD
346 } \
347 \
348 feclearexcept(FE_ALL_EXCEPT); \
349 feenableexcept (FE_ALL_EXCEPT); \
350 if (sigsetjmp(sigfpe_buf, 0)) \
351 { \
67e971f1 352 printf (#FLOAT " fpclassify (sNaN) isnormal SIGFPE\n"); \
5f7aead5
UD
353 errors++; \
354 } else { \
5aa4a1a1
TS
355 check (#FLOAT " fpclassify (sNaN)", \
356 SNAN_TESTS (FLOAT) ? fpclassify (sNaN_var) == FP_NAN : 1); \
5f7aead5
UD
357 } \
358 \
359 feclearexcept(FE_ALL_EXCEPT); \
360 feenableexcept (FE_ALL_EXCEPT); \
361 if (sigsetjmp(sigfpe_buf, 0)) \
362 { \
67e971f1 363 printf (#FLOAT " fpclassify (-sNaN) raised SIGFPE\n"); \
5f7aead5
UD
364 errors++; \
365 } else { \
6cbec759 366 check (#FLOAT " fpclassify (-sNaN)", \
5aa4a1a1 367 SNAN_TESTS (FLOAT) ? fpclassify (minus_sNaN_var) == FP_NAN : 1); \
5f7aead5
UD
368 } \
369 \
370 fesetenv(&saved_fenv); /* restore saved fenv */ \
371 remove_sigaction_FP(); \
372}
373
777b0332
TS
374TEST_FUNC (float_test, float, f)
375TEST_FUNC (double_test, double, )
5f7aead5 376#ifndef NO_LONG_DOUBLE
777b0332 377TEST_FUNC (ldouble_test, ldouble, l)
5f7aead5
UD
378#endif
379
380static int
381do_test (void)
382{
5f7aead5
UD
383 float_test();
384 double_test();
385#ifndef NO_LONG_DOUBLE
386 ldouble_test();
387#endif
388
389 return errors != 0;
390}
391
392#define TEST_FUNCTION do_test ()
393#include "../test-skeleton.c"