]>
Commit | Line | Data |
---|---|---|
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 |
35 | int dest_offset; |
36 | char *dest_address; | |
37 | double value = 123.456; | |
38 | double zero = 0.0; | |
39 | ||
5f7aead5 UD |
40 | static sigjmp_buf sigfpe_buf; |
41 | ||
5f7aead5 UD |
42 | typedef long double ldouble; |
43 | ||
5f7aead5 UD |
44 | |
45 | void | |
46 | myFPsighandler(int signal, | |
47 | siginfo_t *info, | |
48 | void *context) | |
49 | { | |
50 | siglongjmp(sigfpe_buf, 0); | |
51 | } | |
52 | ||
53 | int | |
54 | set_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 | ||
66 | int | |
67 | remove_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 | ||
79 | static int errors = 0; | |
80 | ||
81 | static void | |
82 | check (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 |
91 | static void \ |
92 | NAME (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 |
374 | TEST_FUNC (float_test, float, f) |
375 | TEST_FUNC (double_test, double, ) | |
5f7aead5 | 376 | #ifndef NO_LONG_DOUBLE |
777b0332 | 377 | TEST_FUNC (ldouble_test, ldouble, l) |
5f7aead5 UD |
378 | #endif |
379 | ||
380 | static int | |
381 | do_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" |