]> git.ipfire.org Git - thirdparty/glibc.git/blame - math/test-fenv.c
math: Optimized generic exp10f with wrappers
[thirdparty/glibc.git] / math / test-fenv.c
CommitLineData
d614a753 1/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
762a2918 2 This file is part of the GNU C Library.
60f0e64b 3 Contributed by Andreas Jaeger <aj@suse.de> and
762a2918
UD
4 Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
762a2918
UD
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
41bdb6e2 14 Lesser General Public License for more details.
762a2918 15
41bdb6e2 16 You should have received a copy of the GNU Lesser General Public
59ba27a6 17 License along with the GNU C Library; if not, see
5a82c748 18 <https://www.gnu.org/licenses/>. */
762a2918 19
ec751a23 20/* Tests for ISO C99 7.6: Floating-point environment */
bca973bc
UD
21
22#ifndef _GNU_SOURCE
23# define _GNU_SOURCE
24#endif
25
26#include <complex.h>
27#include <math.h>
28#include <float.h>
29#include <fenv.h>
30
31#include <errno.h>
762a2918 32#include <signal.h>
bca973bc
UD
33#include <stdlib.h>
34#include <stdio.h>
35#include <string.h>
762a2918
UD
36#include <unistd.h>
37#include <sys/wait.h>
74015205 38#include <sys/resource.h>
423a7160 39#include <math-tests.h>
bca973bc
UD
40
41/*
42 Since not all architectures might define all exceptions, we define
43 a private set and map accordingly.
44*/
45#define NO_EXC 0
46#define INEXACT_EXC 0x1
47#define DIVBYZERO_EXC 0x2
48#define UNDERFLOW_EXC 0x04
49#define OVERFLOW_EXC 0x08
50#define INVALID_EXC 0x10
51#define ALL_EXC \
34a5a146
JM
52 (INEXACT_EXC | DIVBYZERO_EXC | UNDERFLOW_EXC | OVERFLOW_EXC \
53 | INVALID_EXC)
bca973bc
UD
54
55static int count_errors;
56
1ff950ad 57#if FE_ALL_EXCEPT
bca973bc
UD
58/* Test whether a given exception was raised. */
59static void
60test_single_exception (short int exception,
61 short int exc_flag,
62 fexcept_t fe_flag,
63 const char *flag_name)
64{
65 if (exception & exc_flag)
66 {
67 if (fetestexcept (fe_flag))
68 printf (" Pass: Exception \"%s\" is set\n", flag_name);
69 else
70 {
71 printf (" Fail: Exception \"%s\" is not set\n", flag_name);
72 ++count_errors;
73 }
74 }
75 else
76 {
77 if (fetestexcept (fe_flag))
78 {
79 printf (" Fail: Exception \"%s\" is set\n", flag_name);
80 ++count_errors;
81 }
82 else
83 {
84 printf (" Pass: Exception \"%s\" is not set\n", flag_name);
85 }
86 }
87}
1ff950ad 88#endif
bca973bc
UD
89
90static void
1522c368
UD
91test_exceptions (const char *test_name, short int exception,
92 int ignore_inexact)
bca973bc
UD
93{
94 printf ("Test: %s\n", test_name);
95#ifdef FE_DIVBYZERO
96 test_single_exception (exception, DIVBYZERO_EXC, FE_DIVBYZERO,
97 "DIVBYZERO");
98#endif
99#ifdef FE_INVALID
100 test_single_exception (exception, INVALID_EXC, FE_INVALID,
101 "INVALID");
102#endif
103#ifdef FE_INEXACT
1522c368
UD
104 if (!ignore_inexact)
105 test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
106 "INEXACT");
bca973bc
UD
107#endif
108#ifdef FE_UNDERFLOW
109 test_single_exception (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
110 "UNDERFLOW");
111#endif
112#ifdef FE_OVERFLOW
113 test_single_exception (exception, OVERFLOW_EXC, FE_OVERFLOW,
114 "OVERFLOW");
115#endif
116}
117
762a2918
UD
118static void
119print_rounding (int rounding)
120{
121
d111572f
UD
122 switch (rounding)
123 {
762a2918 124#ifdef FE_TONEAREST
d111572f
UD
125 case FE_TONEAREST:
126 printf ("TONEAREST");
127 break;
762a2918
UD
128#endif
129#ifdef FE_UPWARD
d111572f
UD
130 case FE_UPWARD:
131 printf ("UPWARD");
132 break;
762a2918
UD
133#endif
134#ifdef FE_DOWNWARD
d111572f
UD
135 case FE_DOWNWARD:
136 printf ("DOWNWARD");
137 break;
762a2918
UD
138#endif
139#ifdef FE_TOWARDZERO
d111572f
UD
140 case FE_TOWARDZERO:
141 printf ("TOWARDZERO");
142 break;
762a2918 143#endif
d111572f 144 }
762a2918
UD
145 printf (".\n");
146}
147
148
149static void
150test_rounding (const char *test_name, int rounding_mode)
151{
152 int curr_rounding = fegetround ();
153
154 printf ("Test: %s\n", test_name);
155 if (curr_rounding == rounding_mode)
156 {
157 printf (" Pass: Rounding mode is ");
158 print_rounding (curr_rounding);
159 }
d111572f
UD
160 else
161 {
162 ++count_errors;
163 printf (" Fail: Rounding mode is ");
164 print_rounding (curr_rounding);
165 }
762a2918
UD
166}
167
bca973bc 168
1ff950ad 169#if FE_ALL_EXCEPT
bca973bc
UD
170static void
171set_single_exc (const char *test_name, int fe_exc, fexcept_t exception)
172{
173 char str[200];
1522c368
UD
174 /* The standard allows the inexact exception to be set together with the
175 underflow and overflow exceptions. So ignore the inexact flag if the
176 others are raised. */
177 int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0;
bca973bc
UD
178
179 strcpy (str, test_name);
180 strcat (str, ": set flag, with rest not set");
181 feclearexcept (FE_ALL_EXCEPT);
182 feraiseexcept (exception);
1522c368 183 test_exceptions (str, fe_exc, ignore_inexact);
bca973bc
UD
184
185 strcpy (str, test_name);
186 strcat (str, ": clear flag, rest also unset");
187 feclearexcept (exception);
1522c368 188 test_exceptions (str, NO_EXC, ignore_inexact);
bca973bc
UD
189
190 strcpy (str, test_name);
191 strcat (str, ": set flag, with rest set");
192 feraiseexcept (FE_ALL_EXCEPT ^ exception);
193 feraiseexcept (exception);
1522c368 194 test_exceptions (str, ALL_EXC, 0);
bca973bc
UD
195
196 strcpy (str, test_name);
197 strcat (str, ": clear flag, leave rest set");
198 feclearexcept (exception);
1522c368 199 test_exceptions (str, ALL_EXC ^ fe_exc, 0);
bca973bc 200}
1ff950ad 201#endif
bca973bc
UD
202
203static void
204fe_tests (void)
205{
206 /* clear all exceptions and test if all are cleared */
207 feclearexcept (FE_ALL_EXCEPT);
208 test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
1522c368 209 NO_EXC, 0);
bca973bc 210
c6be839e
JM
211 /* Skip further tests here if exceptions not supported. */
212 if (!EXCEPTION_TESTS (float) && FE_ALL_EXCEPT != 0)
213 return;
bca973bc
UD
214 /* raise all exceptions and test if all are raised */
215 feraiseexcept (FE_ALL_EXCEPT);
216 test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions",
1522c368 217 ALL_EXC, 0);
bca973bc
UD
218 feclearexcept (FE_ALL_EXCEPT);
219
bca973bc
UD
220#ifdef FE_DIVBYZERO
221 set_single_exc ("Set/Clear FE_DIVBYZERO", DIVBYZERO_EXC, FE_DIVBYZERO);
222#endif
223#ifdef FE_INVALID
224 set_single_exc ("Set/Clear FE_INVALID", INVALID_EXC, FE_INVALID);
225#endif
226#ifdef FE_INEXACT
227 set_single_exc ("Set/Clear FE_INEXACT", INEXACT_EXC, FE_INEXACT);
228#endif
229#ifdef FE_UNDERFLOW
230 set_single_exc ("Set/Clear FE_UNDERFLOW", UNDERFLOW_EXC, FE_UNDERFLOW);
231#endif
232#ifdef FE_OVERFLOW
233 set_single_exc ("Set/Clear FE_OVERFLOW", OVERFLOW_EXC, FE_OVERFLOW);
234#endif
235}
236
1ff950ad 237#if FE_ALL_EXCEPT
762a2918
UD
238/* Test that program aborts with no masked interrupts */
239static void
240feenv_nomask_test (const char *flag_name, int fe_exc)
241{
1ff950ad 242# if defined FE_NOMASK_ENV
762a2918
UD
243 int status;
244 pid_t pid;
423a7160
W
245
246 if (!EXCEPTION_ENABLE_SUPPORTED (FE_ALL_EXCEPT)
247 && fesetenv (FE_NOMASK_ENV) != 0)
0413b54c
UD
248 {
249 printf ("Test: not testing FE_NOMASK_ENV, it isn't implemented.\n");
250 return;
251 }
762a2918
UD
252
253 printf ("Test: after fesetenv (FE_NOMASK_ENV) processes will abort\n");
254 printf (" when feraiseexcept (%s) is called.\n", flag_name);
d111572f 255 pid = fork ();
762a2918
UD
256 if (pid == 0)
257 {
1ff950ad 258# ifdef RLIMIT_CORE
74015205
UD
259 /* Try to avoid dumping core. */
260 struct rlimit core_limit;
261 core_limit.rlim_cur = 0;
262 core_limit.rlim_max = 0;
263 setrlimit (RLIMIT_CORE, &core_limit);
1ff950ad 264# endif
74015205 265
2d7da676 266 fesetenv (FE_NOMASK_ENV);
762a2918
UD
267 feraiseexcept (fe_exc);
268 exit (2);
269 }
270 else if (pid < 0)
271 {
272 if (errno != ENOSYS)
273 {
274 printf (" Fail: Could not fork.\n");
275 ++count_errors;
276 }
277 else
278 printf (" `fork' not implemented, test ignored.\n");
279 }
280 else {
281 if (waitpid (pid, &status, 0) != pid)
282 {
283 printf (" Fail: waitpid call failed.\n");
284 ++count_errors;
285 }
286 else if (WIFSIGNALED (status) && WTERMSIG (status) == SIGFPE)
287 printf (" Pass: Process received SIGFPE.\n");
288 else
289 {
290 printf (" Fail: Process didn't receive signal and exited with status %d.\n",
291 status);
292 ++count_errors;
293 }
294 }
1ff950ad 295# endif
762a2918
UD
296}
297
298/* Test that program doesn't abort with default environment */
299static void
300feenv_mask_test (const char *flag_name, int fe_exc)
301{
302 int status;
303 pid_t pid;
304
305 printf ("Test: after fesetenv (FE_DFL_ENV) processes will not abort\n");
306 printf (" when feraiseexcept (%s) is called.\n", flag_name);
762a2918
UD
307 pid = fork ();
308 if (pid == 0)
309 {
74015205
UD
310#ifdef RLIMIT_CORE
311 /* Try to avoid dumping core. */
312 struct rlimit core_limit;
313 core_limit.rlim_cur = 0;
314 core_limit.rlim_max = 0;
315 setrlimit (RLIMIT_CORE, &core_limit);
316#endif
317
2d7da676 318 fesetenv (FE_DFL_ENV);
762a2918
UD
319 feraiseexcept (fe_exc);
320 exit (2);
321 }
322 else if (pid < 0)
323 {
324 if (errno != ENOSYS)
325 {
326 printf (" Fail: Could not fork.\n");
327 ++count_errors;
328 }
329 else
330 printf (" `fork' not implemented, test ignored.\n");
331 }
332 else {
333 if (waitpid (pid, &status, 0) != pid)
334 {
335 printf (" Fail: waitpid call failed.\n");
336 ++count_errors;
337 }
338 else if (WIFEXITED (status) && WEXITSTATUS (status) == 2)
339 printf (" Pass: Process exited normally.\n");
340 else
341 {
342 printf (" Fail: Process exited abnormally with status %d.\n",
343 status);
344 ++count_errors;
345 }
346 }
347}
348
60f0e64b
UD
349/* Test that program aborts with no masked interrupts */
350static void
351feexcp_nomask_test (const char *flag_name, int fe_exc)
352{
353 int status;
354 pid_t pid;
762a2918 355
423a7160
W
356 if (!EXCEPTION_ENABLE_SUPPORTED (fe_exc) && feenableexcept (fe_exc) == -1)
357 {
358 printf ("Test: not testing feenableexcept, it isn't implemented.\n");
359 return;
360 }
361
362 printf ("Test: after feenableexcept (%s) processes will abort\n",
cca4aa58 363 flag_name);
152461f3 364 printf (" when feraiseexcept (%s) is called.\n", flag_name);
60f0e64b
UD
365 pid = fork ();
366 if (pid == 0)
367 {
368#ifdef RLIMIT_CORE
369 /* Try to avoid dumping core. */
370 struct rlimit core_limit;
371 core_limit.rlim_cur = 0;
372 core_limit.rlim_max = 0;
373 setrlimit (RLIMIT_CORE, &core_limit);
374#endif
762a2918 375
60f0e64b
UD
376 fedisableexcept (FE_ALL_EXCEPT);
377 feenableexcept (fe_exc);
378 feraiseexcept (fe_exc);
379 exit (2);
380 }
381 else if (pid < 0)
382 {
383 if (errno != ENOSYS)
384 {
385 printf (" Fail: Could not fork.\n");
386 ++count_errors;
387 }
388 else
389 printf (" `fork' not implemented, test ignored.\n");
390 }
391 else {
392 if (waitpid (pid, &status, 0) != pid)
393 {
394 printf (" Fail: waitpid call failed.\n");
395 ++count_errors;
396 }
397 else if (WIFSIGNALED (status) && WTERMSIG (status) == SIGFPE)
398 printf (" Pass: Process received SIGFPE.\n");
399 else
400 {
401 printf (" Fail: Process didn't receive signal and exited with status %d.\n",
402 status);
403 ++count_errors;
404 }
405 }
406}
407
408/* Test that program doesn't abort with exception. */
762a2918 409static void
60f0e64b 410feexcp_mask_test (const char *flag_name, int fe_exc)
762a2918 411{
60f0e64b 412 int status;
c0ac34e4 413 int exception;
60f0e64b 414 pid_t pid;
762a2918 415
cca4aa58
UD
416 printf ("Test: after fedisableexcept (%s) processes will not abort\n",
417 flag_name);
152461f3 418 printf (" when feraiseexcept (%s) is called.\n", flag_name);
60f0e64b
UD
419 pid = fork ();
420 if (pid == 0)
421 {
422#ifdef RLIMIT_CORE
423 /* Try to avoid dumping core. */
424 struct rlimit core_limit;
425 core_limit.rlim_cur = 0;
426 core_limit.rlim_max = 0;
427 setrlimit (RLIMIT_CORE, &core_limit);
428#endif
429 feenableexcept (FE_ALL_EXCEPT);
c0ac34e4
UD
430 exception = fe_exc;
431#ifdef FE_INEXACT
432 /* The standard allows the inexact exception to be set together with the
433 underflow and overflow exceptions. So add FE_INEXACT to the set of
434 exceptions to be disabled if we will be raising underflow or
435 overflow. */
436# ifdef FE_OVERFLOW
437 if (fe_exc & FE_OVERFLOW)
438 exception |= FE_INEXACT;
439# endif
440# ifdef FE_UNDERFLOW
441 if (fe_exc & FE_UNDERFLOW)
442 exception |= FE_INEXACT;
443# endif
444#endif
445 fedisableexcept (exception);
60f0e64b
UD
446 feraiseexcept (fe_exc);
447 exit (2);
448 }
449 else if (pid < 0)
450 {
451 if (errno != ENOSYS)
452 {
453 printf (" Fail: Could not fork.\n");
454 ++count_errors;
455 }
456 else
457 printf (" `fork' not implemented, test ignored.\n");
458 }
459 else {
460 if (waitpid (pid, &status, 0) != pid)
461 {
462 printf (" Fail: waitpid call failed.\n");
463 ++count_errors;
464 }
465 else if (WIFEXITED (status) && WEXITSTATUS (status) == 2)
466 printf (" Pass: Process exited normally.\n");
467 else
468 {
469 printf (" Fail: Process exited abnormally with status %d.\n",
470 status);
471 ++count_errors;
472 }
473 }
474}
475
476
477/* Tests for feenableexcept/fedisableexcept/fegetexcept. */
478static void
479feenable_test (const char *flag_name, int fe_exc)
480{
481 int excepts;
482
60f0e64b
UD
483 printf ("Tests for feenableexcepts etc. with flag %s\n", flag_name);
484
485 /* First disable all exceptions. */
486 if (fedisableexcept (FE_ALL_EXCEPT) == -1)
487 {
488 printf ("Test: fedisableexcept (FE_ALL_EXCEPT) failed\n");
489 ++count_errors;
490 /* If this fails, the other tests don't make sense. */
491 return;
492 }
493 excepts = fegetexcept ();
494 if (excepts != 0)
495 {
496 printf ("Test: fegetexcept (%s) failed, return should be 0, is %d\n",
497 flag_name, excepts);
498 ++count_errors;
499 }
60f0e64b 500 excepts = feenableexcept (fe_exc);
423a7160
W
501 if (!EXCEPTION_ENABLE_SUPPORTED (fe_exc) && excepts == -1)
502 {
503 printf ("Test: not testing feenableexcept, it isn't implemented.\n");
504 return;
505 }
60f0e64b
UD
506 if (excepts == -1)
507 {
508 printf ("Test: feenableexcept (%s) failed\n", flag_name);
509 ++count_errors;
510 return;
511 }
512 if (excepts != 0)
513 {
514 printf ("Test: feenableexcept (%s) failed, return should be 0, is %x\n",
515 flag_name, excepts);
516 ++count_errors;
517 }
518
519 excepts = fegetexcept ();
520 if (excepts != fe_exc)
521 {
522 printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
523 flag_name, fe_exc, excepts);
524 ++count_errors;
525 }
526
527 /* And now disable the exception again. */
528 excepts = fedisableexcept (fe_exc);
529 if (excepts == -1)
530 {
531 printf ("Test: fedisableexcept (%s) failed\n", flag_name);
532 ++count_errors;
533 return;
534 }
535 if (excepts != fe_exc)
536 {
537 printf ("Test: fedisableexcept (%s) failed, return should be 0x%x, is 0x%x\n",
538 flag_name, fe_exc, excepts);
539 ++count_errors;
540 }
541
542 excepts = fegetexcept ();
543 if (excepts != 0)
544 {
545 printf ("Test: fegetexcept (%s) failed, return should be 0, is 0x%x\n",
546 flag_name, excepts);
547 ++count_errors;
548 }
549
550 /* Now the other way round: Enable all exceptions and disable just this one. */
551 if (feenableexcept (FE_ALL_EXCEPT) == -1)
552 {
553 printf ("Test: feenableexcept (FE_ALL_EXCEPT) failed\n");
554 ++count_errors;
555 /* If this fails, the other tests don't make sense. */
556 return;
557 }
558
559 excepts = fegetexcept ();
560 if (excepts != FE_ALL_EXCEPT)
561 {
562 printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
563 flag_name, FE_ALL_EXCEPT, excepts);
564 ++count_errors;
565 }
566
567 excepts = fedisableexcept (fe_exc);
568 if (excepts == -1)
569 {
570 printf ("Test: fedisableexcept (%s) failed\n", flag_name);
571 ++count_errors;
572 return;
573 }
574 if (excepts != FE_ALL_EXCEPT)
575 {
576 printf ("Test: fedisableexcept (%s) failed, return should be 0, is 0x%x\n",
577 flag_name, excepts);
578 ++count_errors;
579 }
580
581 excepts = fegetexcept ();
582 if (excepts != (FE_ALL_EXCEPT & ~fe_exc))
583 {
584 printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
585 flag_name, (FE_ALL_EXCEPT & ~fe_exc), excepts);
586 ++count_errors;
587 }
588
589 /* And now enable the exception again. */
590 excepts = feenableexcept (fe_exc);
591 if (excepts == -1)
592 {
593 printf ("Test: feenableexcept (%s) failed\n", flag_name);
594 ++count_errors;
595 return;
596 }
597 if (excepts != (FE_ALL_EXCEPT & ~fe_exc))
598 {
599 printf ("Test: feenableexcept (%s) failed, return should be 0, is 0x%x\n",
600 flag_name, excepts);
601 ++count_errors;
602 }
603
604 excepts = fegetexcept ();
605 if (excepts != FE_ALL_EXCEPT)
606 {
607 printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
608 flag_name, FE_ALL_EXCEPT, excepts);
609 ++count_errors;
610 }
611 feexcp_nomask_test (flag_name, fe_exc);
612 feexcp_mask_test (flag_name, fe_exc);
152461f3 613
60f0e64b
UD
614}
615
616
617static void
618fe_single_test (const char *flag_name, int fe_exc)
619{
620 feenv_nomask_test (flag_name, fe_exc);
621 feenv_mask_test (flag_name, fe_exc);
622 feenable_test (flag_name, fe_exc);
623}
1ff950ad 624#endif
60f0e64b
UD
625
626
627static void
628feenv_tests (void)
629{
152461f3
UD
630 /* We might have some exceptions still set. */
631 feclearexcept (FE_ALL_EXCEPT);
632
762a2918 633#ifdef FE_DIVBYZERO
60f0e64b 634 fe_single_test ("FE_DIVBYZERO", FE_DIVBYZERO);
762a2918
UD
635#endif
636#ifdef FE_INVALID
60f0e64b 637 fe_single_test ("FE_INVALID", FE_INVALID);
762a2918
UD
638#endif
639#ifdef FE_INEXACT
60f0e64b 640 fe_single_test ("FE_INEXACT", FE_INEXACT);
762a2918
UD
641#endif
642#ifdef FE_UNDERFLOW
60f0e64b 643 fe_single_test ("FE_UNDERFLOW", FE_UNDERFLOW);
762a2918
UD
644#endif
645#ifdef FE_OVERFLOW
60f0e64b 646 fe_single_test ("FE_OVERFLOW", FE_OVERFLOW);
762a2918
UD
647#endif
648 fesetenv (FE_DFL_ENV);
649}
650
651
a8c79c40
UD
652static void
653feholdexcept_tests (void)
654{
655 fenv_t saved, saved2;
656 int res;
657
658 feclearexcept (FE_ALL_EXCEPT);
659 fedisableexcept (FE_ALL_EXCEPT);
660#ifdef FE_DIVBYZERO
661 feraiseexcept (FE_DIVBYZERO);
662#endif
c6be839e
JM
663 if (EXCEPTION_TESTS (float))
664 test_exceptions ("feholdexcept_tests FE_DIVBYZERO test",
665 DIVBYZERO_EXC, 0);
a8c79c40
UD
666 res = feholdexcept (&saved);
667 if (res != 0)
668 {
669 printf ("feholdexcept failed: %d\n", res);
670 ++count_errors;
671 }
672#if defined FE_TONEAREST && defined FE_TOWARDZERO
673 res = fesetround (FE_TOWARDZERO);
c6be839e 674 if (res != 0 && ROUNDING_TESTS (float, FE_TOWARDZERO))
a8c79c40
UD
675 {
676 printf ("fesetround failed: %d\n", res);
677 ++count_errors;
678 }
679#endif
680 test_exceptions ("feholdexcept_tests 0 test", NO_EXC, 0);
0af797de 681#ifdef FE_INVALID
a8c79c40 682 feraiseexcept (FE_INVALID);
c6be839e
JM
683 if (EXCEPTION_TESTS (float))
684 test_exceptions ("feholdexcept_tests FE_INVALID test",
685 INVALID_EXC, 0);
0af797de 686#endif
a8c79c40
UD
687 res = feupdateenv (&saved);
688 if (res != 0)
689 {
690 printf ("feupdateenv failed: %d\n", res);
691 ++count_errors;
692 }
693#if defined FE_TONEAREST && defined FE_TOWARDZERO
694 res = fegetround ();
695 if (res != FE_TONEAREST)
696 {
697 printf ("feupdateenv didn't restore rounding mode: %d\n", res);
698 ++count_errors;
699 }
700#endif
c6be839e
JM
701 if (EXCEPTION_TESTS (float))
702 test_exceptions ("feholdexcept_tests FE_DIVBYZERO|FE_INVALID test",
703 DIVBYZERO_EXC | INVALID_EXC, 0);
a8c79c40 704 feclearexcept (FE_ALL_EXCEPT);
0af797de 705#ifdef FE_INVALID
a8c79c40 706 feraiseexcept (FE_INVALID);
0af797de 707#endif
a8c79c40
UD
708#if defined FE_TONEAREST && defined FE_UPWARD
709 res = fesetround (FE_UPWARD);
c6be839e 710 if (res != 0 && ROUNDING_TESTS (float, FE_UPWARD))
a8c79c40
UD
711 {
712 printf ("fesetround failed: %d\n", res);
713 ++count_errors;
714 }
715#endif
716 res = feholdexcept (&saved2);
717 if (res != 0)
718 {
719 printf ("feholdexcept failed: %d\n", res);
720 ++count_errors;
721 }
722#if defined FE_TONEAREST && defined FE_UPWARD
723 res = fesetround (FE_TONEAREST);
724 if (res != 0)
725 {
726 printf ("fesetround failed: %d\n", res);
727 ++count_errors;
728 }
729#endif
730 test_exceptions ("feholdexcept_tests 0 2nd test", NO_EXC, 0);
0af797de 731#ifdef FE_INEXACT
a8c79c40 732 feraiseexcept (FE_INEXACT);
c6be839e
JM
733 if (EXCEPTION_TESTS (float))
734 test_exceptions ("feholdexcept_tests FE_INEXACT test",
735 INEXACT_EXC, 0);
0af797de 736#endif
a8c79c40
UD
737 res = feupdateenv (&saved2);
738 if (res != 0)
739 {
740 printf ("feupdateenv failed: %d\n", res);
741 ++count_errors;
742 }
743#if defined FE_TONEAREST && defined FE_UPWARD
744 res = fegetround ();
c6be839e 745 if (res != FE_UPWARD && ROUNDING_TESTS (float, FE_UPWARD))
a8c79c40
UD
746 {
747 printf ("feupdateenv didn't restore rounding mode: %d\n", res);
748 ++count_errors;
749 }
750 fesetround (FE_TONEAREST);
751#endif
c6be839e
JM
752 if (EXCEPTION_TESTS (float))
753 test_exceptions ("feholdexcept_tests FE_INEXACT|FE_INVALID test",
754 INVALID_EXC | INEXACT_EXC, 0);
a8c79c40
UD
755 feclearexcept (FE_ALL_EXCEPT);
756}
757
758
63ae7b63 759/* IEC 559 and ISO C99 define a default startup environment */
762a2918
UD
760static void
761initial_tests (void)
762{
763 test_exceptions ("Initially all exceptions should be cleared",
1522c368 764 NO_EXC, 0);
efff4ab3 765#ifdef FE_TONEAREST
762a2918
UD
766 test_rounding ("Rounding direction should be initalized to nearest",
767 FE_TONEAREST);
efff4ab3 768#endif
762a2918
UD
769}
770
bca973bc
UD
771int
772main (void)
773{
762a2918 774 initial_tests ();
bca973bc 775 fe_tests ();
762a2918 776 feenv_tests ();
a8c79c40 777 feholdexcept_tests ();
bca973bc
UD
778
779 if (count_errors)
780 {
49c091e5 781 printf ("\n%d errors occurred.\n", count_errors);
bca973bc
UD
782 exit (1);
783 }
784 printf ("\n All tests passed successfully.\n");
767b6275 785 return 0;
bca973bc 786}