test-fenv.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. /* Copyright (C) 1997-2016 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. #ifdef __UCLIBC_HAS_FENV__
  24. #include <fenv.h>
  25. #endif
  26. #include <errno.h>
  27. #include <signal.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <unistd.h>
  32. #include <sys/wait.h>
  33. #include <sys/resource.h>
  34. #include "math-tests.h"
  35. #ifdef __UCLIBC_HAS_FENV__
  36. /*
  37. Since not all architectures might define all exceptions, we define
  38. a private set and map accordingly.
  39. */
  40. #define NO_EXC 0
  41. #define INEXACT_EXC 0x1
  42. #define DIVBYZERO_EXC 0x2
  43. #define UNDERFLOW_EXC 0x04
  44. #define OVERFLOW_EXC 0x08
  45. #define INVALID_EXC 0x10
  46. #define ALL_EXC \
  47. (INEXACT_EXC | DIVBYZERO_EXC | UNDERFLOW_EXC | OVERFLOW_EXC | \
  48. INVALID_EXC)
  49. static int count_errors;
  50. #if FE_ALL_EXCEPT
  51. /* Test whether a given exception was raised. */
  52. static void
  53. test_single_exception (short int exception,
  54. short int exc_flag,
  55. fexcept_t fe_flag,
  56. const char *flag_name)
  57. {
  58. if (exception & exc_flag)
  59. {
  60. if (fetestexcept (fe_flag))
  61. printf (" Pass: Exception \"%s\" is set\n", flag_name);
  62. else
  63. {
  64. printf (" Fail: Exception \"%s\" is not set\n", flag_name);
  65. ++count_errors;
  66. }
  67. }
  68. else
  69. {
  70. if (fetestexcept (fe_flag))
  71. {
  72. printf (" Fail: Exception \"%s\" is set\n", flag_name);
  73. ++count_errors;
  74. }
  75. else
  76. {
  77. printf (" Pass: Exception \"%s\" is not set\n", flag_name);
  78. }
  79. }
  80. }
  81. #endif
  82. static void
  83. test_exceptions (const char *test_name, short int exception,
  84. int ignore_inexact)
  85. {
  86. printf ("Test: %s\n", test_name);
  87. #ifdef FE_DIVBYZERO
  88. test_single_exception (exception, DIVBYZERO_EXC, FE_DIVBYZERO,
  89. "DIVBYZERO");
  90. #endif
  91. #ifdef FE_INVALID
  92. test_single_exception (exception, INVALID_EXC, FE_INVALID,
  93. "INVALID");
  94. #endif
  95. #ifdef FE_INEXACT
  96. if (!ignore_inexact)
  97. test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
  98. "INEXACT");
  99. #endif
  100. #ifdef FE_UNDERFLOW
  101. test_single_exception (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
  102. "UNDERFLOW");
  103. #endif
  104. #ifdef FE_OVERFLOW
  105. test_single_exception (exception, OVERFLOW_EXC, FE_OVERFLOW,
  106. "OVERFLOW");
  107. #endif
  108. }
  109. static void
  110. print_rounding (int rounding)
  111. {
  112. switch (rounding)
  113. {
  114. #ifdef FE_TONEAREST
  115. case FE_TONEAREST:
  116. printf ("TONEAREST");
  117. break;
  118. #endif
  119. #ifdef FE_UPWARD
  120. case FE_UPWARD:
  121. printf ("UPWARD");
  122. break;
  123. #endif
  124. #ifdef FE_DOWNWARD
  125. case FE_DOWNWARD:
  126. printf ("DOWNWARD");
  127. break;
  128. #endif
  129. #ifdef FE_TOWARDZERO
  130. case FE_TOWARDZERO:
  131. printf ("TOWARDZERO");
  132. break;
  133. #endif
  134. }
  135. printf (".\n");
  136. }
  137. static void
  138. test_rounding (const char *test_name, int rounding_mode)
  139. {
  140. int curr_rounding = fegetround ();
  141. printf ("Test: %s\n", test_name);
  142. if (curr_rounding == rounding_mode)
  143. {
  144. printf (" Pass: Rounding mode is ");
  145. print_rounding (curr_rounding);
  146. }
  147. else
  148. {
  149. ++count_errors;
  150. printf (" Fail: Rounding mode is ");
  151. print_rounding (curr_rounding);
  152. }
  153. }
  154. #if FE_ALL_EXCEPT
  155. static void
  156. set_single_exc (const char *test_name, int fe_exc, fexcept_t exception)
  157. {
  158. char str[200];
  159. /* The standard allows the inexact exception to be set together with the
  160. underflow and overflow exceptions. So ignore the inexact flag if the
  161. others are raised. */
  162. int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0;
  163. strcpy (str, test_name);
  164. strcat (str, ": set flag, with rest not set");
  165. feclearexcept (FE_ALL_EXCEPT);
  166. feraiseexcept (exception);
  167. test_exceptions (str, fe_exc, ignore_inexact);
  168. strcpy (str, test_name);
  169. strcat (str, ": clear flag, rest also unset");
  170. feclearexcept (exception);
  171. test_exceptions (str, NO_EXC, ignore_inexact);
  172. strcpy (str, test_name);
  173. strcat (str, ": set flag, with rest set");
  174. feraiseexcept (FE_ALL_EXCEPT ^ exception);
  175. feraiseexcept (exception);
  176. test_exceptions (str, ALL_EXC, 0);
  177. strcpy (str, test_name);
  178. strcat (str, ": clear flag, leave rest set");
  179. feclearexcept (exception);
  180. test_exceptions (str, ALL_EXC ^ fe_exc, 0);
  181. }
  182. #endif
  183. static void
  184. fe_tests (void)
  185. {
  186. /* clear all exceptions and test if all are cleared */
  187. feclearexcept (FE_ALL_EXCEPT);
  188. test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
  189. NO_EXC, 0);
  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. test_exceptions ("feholdexcept_tests FE_DIVBYZERO test",
  604. DIVBYZERO_EXC, 0);
  605. res = feholdexcept (&saved);
  606. if (res != 0)
  607. {
  608. printf ("feholdexcept failed: %d\n", res);
  609. ++count_errors;
  610. }
  611. #if defined FE_TONEAREST && defined FE_TOWARDZERO
  612. res = fesetround (FE_TOWARDZERO);
  613. if (res != 0)
  614. {
  615. printf ("fesetround failed: %d\n", res);
  616. ++count_errors;
  617. }
  618. #endif
  619. test_exceptions ("feholdexcept_tests 0 test", NO_EXC, 0);
  620. #ifdef FE_INVALID
  621. feraiseexcept (FE_INVALID);
  622. test_exceptions ("feholdexcept_tests FE_INVALID test",
  623. INVALID_EXC, 0);
  624. #endif
  625. res = feupdateenv (&saved);
  626. if (res != 0)
  627. {
  628. printf ("feupdateenv failed: %d\n", res);
  629. ++count_errors;
  630. }
  631. #if defined FE_TONEAREST && defined FE_TOWARDZERO
  632. res = fegetround ();
  633. if (res != FE_TONEAREST)
  634. {
  635. printf ("feupdateenv didn't restore rounding mode: %d\n", res);
  636. ++count_errors;
  637. }
  638. #endif
  639. test_exceptions ("feholdexcept_tests FE_DIVBYZERO|FE_INVALID test",
  640. DIVBYZERO_EXC | INVALID_EXC, 0);
  641. feclearexcept (FE_ALL_EXCEPT);
  642. #ifdef FE_INVALID
  643. feraiseexcept (FE_INVALID);
  644. #endif
  645. #if defined FE_TONEAREST && defined FE_UPWARD
  646. res = fesetround (FE_UPWARD);
  647. if (res != 0)
  648. {
  649. printf ("fesetround failed: %d\n", res);
  650. ++count_errors;
  651. }
  652. #endif
  653. res = feholdexcept (&saved2);
  654. if (res != 0)
  655. {
  656. printf ("feholdexcept failed: %d\n", res);
  657. ++count_errors;
  658. }
  659. #if defined FE_TONEAREST && defined FE_UPWARD
  660. res = fesetround (FE_TONEAREST);
  661. if (res != 0)
  662. {
  663. printf ("fesetround failed: %d\n", res);
  664. ++count_errors;
  665. }
  666. #endif
  667. test_exceptions ("feholdexcept_tests 0 2nd test", NO_EXC, 0);
  668. #ifdef FE_INEXACT
  669. feraiseexcept (FE_INEXACT);
  670. test_exceptions ("feholdexcept_tests FE_INEXACT test",
  671. INEXACT_EXC, 0);
  672. #endif
  673. res = feupdateenv (&saved2);
  674. if (res != 0)
  675. {
  676. printf ("feupdateenv failed: %d\n", res);
  677. ++count_errors;
  678. }
  679. #if defined FE_TONEAREST && defined FE_UPWARD
  680. res = fegetround ();
  681. if (res != FE_UPWARD)
  682. {
  683. printf ("feupdateenv didn't restore rounding mode: %d\n", res);
  684. ++count_errors;
  685. }
  686. fesetround (FE_TONEAREST);
  687. #endif
  688. test_exceptions ("feholdexcept_tests FE_INEXACT|FE_INVALID test",
  689. INVALID_EXC | INEXACT_EXC, 0);
  690. feclearexcept (FE_ALL_EXCEPT);
  691. }
  692. /* IEC 559 and ISO C99 define a default startup environment */
  693. static void
  694. initial_tests (void)
  695. {
  696. test_exceptions ("Initially all exceptions should be cleared",
  697. NO_EXC, 0);
  698. #ifdef FE_TONEAREST
  699. test_rounding ("Rounding direction should be initalized to nearest",
  700. FE_TONEAREST);
  701. #endif
  702. }
  703. #endif
  704. int
  705. main (void)
  706. {
  707. #ifdef __UCLIBC_HAS_FENV__
  708. initial_tests ();
  709. fe_tests ();
  710. feenv_tests ();
  711. feholdexcept_tests ();
  712. if (count_errors)
  713. {
  714. printf ("\n%d errors occurred.\n", count_errors);
  715. exit (1);
  716. }
  717. printf ("\n All tests passed successfully.\n");
  718. return 0;
  719. #else
  720. return 23;
  721. #endif
  722. }