openat: don’t close (-1)
[gnulib.git] / tests / test-fenv-except-state-2.c
blob79b6f9fd38cd2cd02181a460f545f5bbfc9e9608
1 /* Test of saving the floating-point exception status flags.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program 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
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2023. */
19 #include <config.h>
21 /* Specification. */
22 #include <fenv.h>
24 #include "macros.h"
26 int
27 main ()
29 fexcept_t saved_flags_1;
30 fexcept_t saved_flags_2;
32 /* Test setting all exception flags. */
33 if (feraiseexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) != 0)
35 fputs ("Skipping test: floating-point exceptions are not supported on this machine.\n", stderr);
36 return 77;
39 /* Fill saved_flags_1. */
40 ASSERT (fegetexceptflag (&saved_flags_1,
41 FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
42 == 0);
44 /* Clear some of the exception flags. */
45 ASSERT (feclearexcept (FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) == 0);
46 /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO. */
47 ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
48 ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
49 ASSERT (fetestexcept (FE_OVERFLOW) == 0);
50 ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
51 ASSERT (fetestexcept (FE_INEXACT) == 0);
53 /* Fill saved_flags_2. */
54 ASSERT (fegetexceptflag (&saved_flags_2, FE_INVALID | FE_OVERFLOW) == 0);
56 /* Restore some of the exception flags. */
57 ASSERT (fesetexceptflag (&saved_flags_1,
58 FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) == 0);
59 /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW. */
60 ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
61 ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
62 ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
63 ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
64 ASSERT (fetestexcept (FE_INEXACT) == 0);
66 /* Clear some more exception flags. */
67 ASSERT (feclearexcept (FE_INVALID) == 0);
68 /* Here, the set exception flags are FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW. */
69 ASSERT (fetestexcept (FE_INVALID) == 0);
70 ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
71 ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
72 ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
73 ASSERT (fetestexcept (FE_INEXACT) == 0);
75 /* Restore some more exception flags. */
76 ASSERT (fesetexceptflag (&saved_flags_2, FE_OVERFLOW) == 0);
77 /* Here, the set exception flags are FE_DIVBYZERO | FE_UNDERFLOW. */
78 ASSERT (fetestexcept (FE_INVALID) == 0);
79 ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
80 ASSERT (fetestexcept (FE_OVERFLOW) == 0);
81 ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
82 ASSERT (fetestexcept (FE_INEXACT) == 0);
84 /* Restore some more exception flags. */
85 ASSERT (fesetexceptflag (&saved_flags_2, FE_INVALID) == 0);
86 /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO | FE_UNDERFLOW. */
87 ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
88 ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
89 ASSERT (fetestexcept (FE_OVERFLOW) == 0);
90 ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
91 ASSERT (fetestexcept (FE_INEXACT) == 0);
93 /* ======================================================================== */
94 /* Check that fesetexceptflag clears exception flags in both the 387 unit
95 and the SSE unit, on i386 and x86_64 CPUs. */
97 fexcept_t saved_flags_3;
99 ASSERT (feclearexcept (FE_INVALID) == 0);
101 ASSERT (fegetexceptflag (&saved_flags_3, FE_INVALID) == 0);
103 /* Set the FE_INVALID flag in the SSE unit. */
105 static volatile double a, b;
106 _GL_UNUSED volatile double c;
107 a = 0.0; b = 0.0; c = a / b;
109 /* Set the FE_INVALID flag in the 387 unit. */
111 static volatile long double al, bl;
112 _GL_UNUSED volatile long double cl;
113 al = 0.0L; bl = 0.0L; cl = al / bl;
116 /* Use fesetexceptflag to clear the FE_INVALID flag. */
117 ASSERT (fesetexceptflag (&saved_flags_3, FE_INVALID) == 0);
119 /* Check that it's clear in both units. */
120 ASSERT (fetestexcept (FE_INVALID) == 0);
122 return test_exit_status;