+2023-11-07 Bruno Haible <bruno@clisp.org>
+
+ fenv-exceptions-state-c99 tests: Add a test of the link dependencies.
+ * tests/test-fenv-except-state-4.c: Renamed from
+ tests/test-fenv-except-state-3.c.
+ * tests/test-fenv-except-state-3.c: Renamed from
+ tests/test-fenv-except-state-2.c.
+ * tests/test-fenv-except-state-2.c: Renamed from
+ tests/test-fenv-except-state-1.c.
+ * tests/test-fenv-except-state-1.c: New file.
+ * modules/fenv-exceptions-state-c23-tests: Update.
+ * modules/fenv-exceptions-state-c99-tests: Update. Add
+ test-fenv-except-state-1 unit test.
+
2023-11-07 Bruno Haible <bruno@clisp.org>
fenv-exceptions-trapping tests: Comments.
Files:
-tests/test-fenv-except-state-3.c
+tests/test-fenv-except-state-4.c
tests/macros.h
Depends-on:
configure.ac:
Makefile.am:
-TESTS += test-fenv-except-state-3
-check_PROGRAMS += test-fenv-except-state-3
-test_fenv_except_state_3_LDADD = $(LDADD) @FENV_EXCEPTIONS_STATE_LIBM@ $(FENV_EXCEPTIONS_TRACKING_LIBM)
+TESTS += test-fenv-except-state-4
+check_PROGRAMS += test-fenv-except-state-4
+test_fenv_except_state_4_LDADD = $(LDADD) @FENV_EXCEPTIONS_STATE_LIBM@ $(FENV_EXCEPTIONS_TRACKING_LIBM)
Files:
tests/test-fenv-except-state-1.c
tests/test-fenv-except-state-2.c
+tests/test-fenv-except-state-3.c
tests/macros.h
m4/musl.m4
Makefile.am:
TESTS += \
test-fenv-except-state-1 \
- test-fenv-except-state-2
+ test-fenv-except-state-2 \
+ test-fenv-except-state-3
check_PROGRAMS += \
test-fenv-except-state-1 \
- test-fenv-except-state-2
-test_fenv_except_state_1_LDADD = $(LDADD) @FENV_EXCEPTIONS_STATE_LIBM@ $(FENV_EXCEPTIONS_TRACKING_LIBM)
-test_fenv_except_state_2_LDADD = $(LDADD) @FENV_EXCEPTIONS_STATE_LIBM@ $(FENV_EXCEPTIONS_TRACKING_LIBM) @FPE_TRAPPING_LIBM@
+ test-fenv-except-state-2 \
+ test-fenv-except-state-3
+test_fenv_except_state_1_LDADD = $(LDADD) @FENV_EXCEPTIONS_STATE_LIBM@
+test_fenv_except_state_2_LDADD = $(LDADD) @FENV_EXCEPTIONS_STATE_LIBM@ $(FENV_EXCEPTIONS_TRACKING_LIBM)
+test_fenv_except_state_3_LDADD = $(LDADD) @FENV_EXCEPTIONS_STATE_LIBM@ $(FENV_EXCEPTIONS_TRACKING_LIBM) @FPE_TRAPPING_LIBM@
/* Specification. */
#include <fenv.h>
-#include "macros.h"
+/* Test the link dependencies: that $(FENV_EXCEPTIONS_STATE_LIBM) is
+ sufficient. */
int
main ()
{
- fexcept_t saved_flags_1;
- fexcept_t saved_flags_2;
+ fexcept_t saved_flags;
- /* Test setting all exception flags. */
- if (feraiseexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) != 0)
- {
- fputs ("Skipping test: floating-point exceptions are not supported on this machine.\n", stderr);
- return 77;
- }
-
- /* Fill saved_flags_1. */
- ASSERT (fegetexceptflag (&saved_flags_1,
- FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
- == 0);
-
- /* Clear some of the exception flags. */
- ASSERT (feclearexcept (FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) == 0);
- /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO. */
- ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
- ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
- ASSERT (fetestexcept (FE_OVERFLOW) == 0);
- ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
- ASSERT (fetestexcept (FE_INEXACT) == 0);
-
- /* Fill saved_flags_2. */
- ASSERT (fegetexceptflag (&saved_flags_2, FE_INVALID | FE_OVERFLOW) == 0);
-
- /* Restore some of the exception flags. */
- ASSERT (fesetexceptflag (&saved_flags_1,
- FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) == 0);
- /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW. */
- ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
- ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
- ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
- ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
- ASSERT (fetestexcept (FE_INEXACT) == 0);
-
- /* Clear some more exception flags. */
- ASSERT (feclearexcept (FE_INVALID) == 0);
- /* Here, the set exception flags are FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW. */
- ASSERT (fetestexcept (FE_INVALID) == 0);
- ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
- ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
- ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
- ASSERT (fetestexcept (FE_INEXACT) == 0);
-
- /* Restore some more exception flags. */
- ASSERT (fesetexceptflag (&saved_flags_2, FE_OVERFLOW) == 0);
- /* Here, the set exception flags are FE_DIVBYZERO | FE_UNDERFLOW. */
- ASSERT (fetestexcept (FE_INVALID) == 0);
- ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
- ASSERT (fetestexcept (FE_OVERFLOW) == 0);
- ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
- ASSERT (fetestexcept (FE_INEXACT) == 0);
-
- /* Restore some more exception flags. */
- ASSERT (fesetexceptflag (&saved_flags_2, FE_INVALID) == 0);
- /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO | FE_UNDERFLOW. */
- ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
- ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
- ASSERT (fetestexcept (FE_OVERFLOW) == 0);
- ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
- ASSERT (fetestexcept (FE_INEXACT) == 0);
-
- /* ======================================================================== */
- /* Check that fesetexceptflag clears exception flags in both the 387 unit
- and the SSE unit, on i386 and x86_64 CPUs. */
-
- fexcept_t saved_flags_3;
-
- ASSERT (feclearexcept (FE_INVALID) == 0);
-
- ASSERT (fegetexceptflag (&saved_flags_3, FE_INVALID) == 0);
-
- /* Set the FE_INVALID flag in the SSE unit. */
- {
- static volatile double a, b;
- _GL_UNUSED volatile double c;
- a = 0.0; b = 0.0; c = a / b;
- }
- /* Set the FE_INVALID flag in the 387 unit. */
- {
- static volatile long double al, bl;
- _GL_UNUSED volatile long double cl;
- al = 0.0L; bl = 0.0L; cl = al / bl;
- }
-
- /* Use fesetexceptflag to clear the FE_INVALID flag. */
- ASSERT (fesetexceptflag (&saved_flags_3, FE_INVALID) == 0);
-
- /* Check that it's clear in both units. */
- ASSERT (fetestexcept (FE_INVALID) == 0);
+ fegetexceptflag (&saved_flags, FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT);
+ fesetexceptflag (&saved_flags, FE_OVERFLOW | FE_UNDERFLOW);
return 0;
}
/* Specification. */
#include <fenv.h>
-#include <stdio.h>
-
-#include "fpe-trapping.h"
#include "macros.h"
-/* musl libc does not support floating-point exception trapping, even where
- the hardware supports it. See
- <https://wiki.musl-libc.org/functional-differences-from-glibc.html> */
-#if HAVE_FPE_TRAPPING && (!MUSL_LIBC || GNULIB_FEENABLEEXCEPT)
-
-/* Check that fesetexceptflag() does not trigger a trap. */
-
-static volatile double a, b;
-static volatile long double al, bl;
-
int
main ()
{
fexcept_t saved_flags_1;
+ fexcept_t saved_flags_2;
/* Test setting all exception flags. */
if (feraiseexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) != 0)
FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
== 0);
- /* Clear exceptions from past operations. */
- feclearexcept (FE_ALL_EXCEPT);
-
- /* An FE_INVALID exception shall trigger a SIGFPE signal, which by default
- terminates the program. */
- if (sigfpe_on_invalid () < 0)
- {
- fputs ("Skipping test: trapping floating-point exceptions are not supported on this machine.\n", stderr);
- return 77;
- }
-
- /* Attempt to set the FE_INVALID exception flag. */
- _GL_UNUSED int rc = fesetexceptflag (&saved_flags_1, FE_INVALID);
- /* On older i386 and on PowerPC, there is no way to implement
- fesetexceptflag() such that it does not trigger a trap. fesetexceptflag()
- is expected to fail in this case. */
-# if !((defined __i386 || defined _M_IX86) || defined __powerpc__)
- ASSERT (rc == 0);
-# endif
-
- /* Do a harmless floating-point operation (since on some CPUs, floating-point
- exceptions trigger a trap only at the next floating-point operation). */
- a = 1.0; b = a + a;
- al = 1.0L; bl = al + al;
+ /* Clear some of the exception flags. */
+ ASSERT (feclearexcept (FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) == 0);
+ /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO. */
+ ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
+ ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+ ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+ ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
+ ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+ /* Fill saved_flags_2. */
+ ASSERT (fegetexceptflag (&saved_flags_2, FE_INVALID | FE_OVERFLOW) == 0);
+
+ /* Restore some of the exception flags. */
+ ASSERT (fesetexceptflag (&saved_flags_1,
+ FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) == 0);
+ /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW. */
+ ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
+ ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+ ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
+ ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+ ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+ /* Clear some more exception flags. */
+ ASSERT (feclearexcept (FE_INVALID) == 0);
+ /* Here, the set exception flags are FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW. */
+ ASSERT (fetestexcept (FE_INVALID) == 0);
+ ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+ ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
+ ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+ ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+ /* Restore some more exception flags. */
+ ASSERT (fesetexceptflag (&saved_flags_2, FE_OVERFLOW) == 0);
+ /* Here, the set exception flags are FE_DIVBYZERO | FE_UNDERFLOW. */
+ ASSERT (fetestexcept (FE_INVALID) == 0);
+ ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+ ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+ ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+ ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+ /* Restore some more exception flags. */
+ ASSERT (fesetexceptflag (&saved_flags_2, FE_INVALID) == 0);
+ /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO | FE_UNDERFLOW. */
+ ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
+ ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+ ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+ ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+ ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+ /* ======================================================================== */
+ /* Check that fesetexceptflag clears exception flags in both the 387 unit
+ and the SSE unit, on i386 and x86_64 CPUs. */
+
+ fexcept_t saved_flags_3;
+
+ ASSERT (feclearexcept (FE_INVALID) == 0);
+
+ ASSERT (fegetexceptflag (&saved_flags_3, FE_INVALID) == 0);
+
+ /* Set the FE_INVALID flag in the SSE unit. */
+ {
+ static volatile double a, b;
+ _GL_UNUSED volatile double c;
+ a = 0.0; b = 0.0; c = a / b;
+ }
+ /* Set the FE_INVALID flag in the 387 unit. */
+ {
+ static volatile long double al, bl;
+ _GL_UNUSED volatile long double cl;
+ al = 0.0L; bl = 0.0L; cl = al / bl;
+ }
+
+ /* Use fesetexceptflag to clear the FE_INVALID flag. */
+ ASSERT (fesetexceptflag (&saved_flags_3, FE_INVALID) == 0);
+
+ /* Check that it's clear in both units. */
+ ASSERT (fetestexcept (FE_INVALID) == 0);
return 0;
}
-
-#else
-
-int
-main ()
-{
- fputs ("Skipping test: feenableexcept not available\n", stderr);
- return 77;
-}
-
-#endif
/* Specification. */
#include <fenv.h>
+#include <stdio.h>
+
+#include "fpe-trapping.h"
#include "macros.h"
+/* musl libc does not support floating-point exception trapping, even where
+ the hardware supports it. See
+ <https://wiki.musl-libc.org/functional-differences-from-glibc.html> */
+#if HAVE_FPE_TRAPPING && (!MUSL_LIBC || GNULIB_FEENABLEEXCEPT)
+
+/* Check that fesetexceptflag() does not trigger a trap. */
+
+static volatile double a, b;
+static volatile long double al, bl;
+
int
main ()
{
fexcept_t saved_flags_1;
- fexcept_t saved_flags_2;
/* Test setting all exception flags. */
if (feraiseexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) != 0)
ASSERT (fegetexceptflag (&saved_flags_1,
FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
== 0);
- /* Check its contents. */
- ASSERT (fetestexceptflag (&saved_flags_1,
- FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
- == (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT));
- ASSERT (fetestexceptflag (&saved_flags_1, FE_INVALID) == FE_INVALID);
- ASSERT (fetestexceptflag (&saved_flags_1, FE_DIVBYZERO) == FE_DIVBYZERO);
- ASSERT (fetestexceptflag (&saved_flags_1, FE_OVERFLOW) == FE_OVERFLOW);
- ASSERT (fetestexceptflag (&saved_flags_1, FE_UNDERFLOW) == FE_UNDERFLOW);
- ASSERT (fetestexceptflag (&saved_flags_1, FE_INEXACT) == FE_INEXACT);
-
- /* Clear some of the exception flags. */
- ASSERT (feclearexcept (FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) == 0);
- /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO. */
- ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
- ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
- ASSERT (fetestexcept (FE_OVERFLOW) == 0);
- ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
- ASSERT (fetestexcept (FE_INEXACT) == 0);
-
- /* Fill saved_flags_2. */
- ASSERT (fegetexceptflag (&saved_flags_2, FE_INVALID | FE_OVERFLOW) == 0);
- /* Check its contents. */
- ASSERT (fetestexceptflag (&saved_flags_2, FE_INVALID | FE_OVERFLOW) == FE_INVALID);
- ASSERT (fetestexceptflag (&saved_flags_2, FE_INVALID) == FE_INVALID);
- ASSERT (fetestexceptflag (&saved_flags_2, FE_OVERFLOW) == 0);
+
+ /* Clear exceptions from past operations. */
+ feclearexcept (FE_ALL_EXCEPT);
+
+ /* An FE_INVALID exception shall trigger a SIGFPE signal, which by default
+ terminates the program. */
+ if (sigfpe_on_invalid () < 0)
+ {
+ fputs ("Skipping test: trapping floating-point exceptions are not supported on this machine.\n", stderr);
+ return 77;
+ }
+
+ /* Attempt to set the FE_INVALID exception flag. */
+ _GL_UNUSED int rc = fesetexceptflag (&saved_flags_1, FE_INVALID);
+ /* On older i386 and on PowerPC, there is no way to implement
+ fesetexceptflag() such that it does not trigger a trap. fesetexceptflag()
+ is expected to fail in this case. */
+# if !((defined __i386 || defined _M_IX86) || defined __powerpc__)
+ ASSERT (rc == 0);
+# endif
+
+ /* Do a harmless floating-point operation (since on some CPUs, floating-point
+ exceptions trigger a trap only at the next floating-point operation). */
+ a = 1.0; b = a + a;
+ al = 1.0L; bl = al + al;
return 0;
}
+
+#else
+
+int
+main ()
+{
+ fputs ("Skipping test: feenableexcept not available\n", stderr);
+ return 77;
+}
+
+#endif
--- /dev/null
+/* Test of saving the floating-point exception status flags.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+#include <config.h>
+
+/* Specification. */
+#include <fenv.h>
+
+#include "macros.h"
+
+int
+main ()
+{
+ fexcept_t saved_flags_1;
+ fexcept_t saved_flags_2;
+
+ /* Test setting all exception flags. */
+ if (feraiseexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) != 0)
+ {
+ fputs ("Skipping test: floating-point exceptions are not supported on this machine.\n", stderr);
+ return 77;
+ }
+
+ /* Fill saved_flags_1. */
+ ASSERT (fegetexceptflag (&saved_flags_1,
+ FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+ == 0);
+ /* Check its contents. */
+ ASSERT (fetestexceptflag (&saved_flags_1,
+ FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+ == (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT));
+ ASSERT (fetestexceptflag (&saved_flags_1, FE_INVALID) == FE_INVALID);
+ ASSERT (fetestexceptflag (&saved_flags_1, FE_DIVBYZERO) == FE_DIVBYZERO);
+ ASSERT (fetestexceptflag (&saved_flags_1, FE_OVERFLOW) == FE_OVERFLOW);
+ ASSERT (fetestexceptflag (&saved_flags_1, FE_UNDERFLOW) == FE_UNDERFLOW);
+ ASSERT (fetestexceptflag (&saved_flags_1, FE_INEXACT) == FE_INEXACT);
+
+ /* Clear some of the exception flags. */
+ ASSERT (feclearexcept (FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) == 0);
+ /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO. */
+ ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
+ ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+ ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+ ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
+ ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+ /* Fill saved_flags_2. */
+ ASSERT (fegetexceptflag (&saved_flags_2, FE_INVALID | FE_OVERFLOW) == 0);
+ /* Check its contents. */
+ ASSERT (fetestexceptflag (&saved_flags_2, FE_INVALID | FE_OVERFLOW) == FE_INVALID);
+ ASSERT (fetestexceptflag (&saved_flags_2, FE_INVALID) == FE_INVALID);
+ ASSERT (fetestexceptflag (&saved_flags_2, FE_OVERFLOW) == 0);
+
+ return 0;
+}