test-fenv.c 19 KB

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