]> Savannah Git Hosting - gnulib.git/commitdiff
fenv-exceptions-tracking-c23: Add tests.
authorBruno Haible <bruno@clisp.org>
Sun, 29 Oct 2023 21:27:38 +0000 (22:27 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 29 Oct 2023 21:28:50 +0000 (22:28 +0100)
* tests/test-fenv-except-tracking-4.c: New file.
* tests/test-fenv-except-tracking-5.c: New file.
* modules/fenv-exceptions-tracking-c23-tests: New file.

ChangeLog
modules/fenv-exceptions-tracking-c23-tests [new file with mode: 0644]
tests/test-fenv-except-tracking-4.c [new file with mode: 0644]
tests/test-fenv-except-tracking-5.c [new file with mode: 0644]

index 36256c30e4db408515bf9261c18a076dbbab44c0..26686c3fb8625d37b700d4ac422f147b4aa65639 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2023-10-29  Bruno Haible  <bruno@clisp.org>
 
+       fenv-exceptions-tracking-c23: Add tests.
+       * tests/test-fenv-except-tracking-4.c: New file.
+       * tests/test-fenv-except-tracking-5.c: New file.
+       * modules/fenv-exceptions-tracking-c23-tests: New file.
+
        fenv-exceptions-tracking-c23: New module.
        * lib/fenv.in.h (fesetexcept): New declaration.
        * lib/fenv-except-tracking-set.c: New file, based on glibc.
diff --git a/modules/fenv-exceptions-tracking-c23-tests b/modules/fenv-exceptions-tracking-c23-tests
new file mode 100644 (file)
index 0000000..4c39f00
--- /dev/null
@@ -0,0 +1,21 @@
+Files:
+tests/test-fenv-except-tracking-4.c
+tests/test-fenv-except-tracking-5.c
+tests/macros.h
+m4/musl.m4
+
+Depends-on:
+fpe-trapping
+
+configure.ac:
+gl_MUSL_LIBC
+
+Makefile.am:
+TESTS += \
+  test-fenv-except-tracking-4 \
+  test-fenv-except-tracking-5
+check_PROGRAMS += \
+  test-fenv-except-tracking-4 \
+  test-fenv-except-tracking-5
+test_fenv_except_tracking_4_LDADD = $(LDADD) @FENV_EXCEPTIONS_TRACKING_LIBM@
+test_fenv_except_tracking_5_LDADD = $(LDADD) @FENV_EXCEPTIONS_TRACKING_LIBM@ @FPE_TRAPPING_LIBM@
diff --git a/tests/test-fenv-except-tracking-4.c b/tests/test-fenv-except-tracking-4.c
new file mode 100644 (file)
index 0000000..30c4f02
--- /dev/null
@@ -0,0 +1,94 @@
+/* Test of tracking of floating-point exceptions.
+   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"
+
+/* Check that fesetexcept() works.  */
+
+int
+main ()
+{
+  /* Test setting all exception flags.  */
+  if (feraiseexcept (FE_ALL_EXCEPT) != 0)
+    {
+      fputs ("Skipping test: floating-point exceptions are not supported on this machine.\n", stderr);
+      return 77;
+    }
+
+  /* Clear all exception flags.  */
+  ASSERT (feclearexcept (FE_ALL_EXCEPT) == 0);
+
+
+  /* Test setting just one exception flag: FE_INVALID.  */
+  ASSERT (feclearexcept (FE_ALL_EXCEPT) == 0);
+  ASSERT (fesetexcept (FE_INVALID) == 0);
+  ASSERT (fetestexcept (FE_ALL_EXCEPT) == FE_INVALID);
+  ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == 0);
+  ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /* Test setting just one exception flag: FE_DIVBYZERO.  */
+  ASSERT (feclearexcept (FE_ALL_EXCEPT) == 0);
+  ASSERT (fesetexcept (FE_DIVBYZERO) == 0);
+  ASSERT (fetestexcept (FE_ALL_EXCEPT) == FE_DIVBYZERO);
+  ASSERT (fetestexcept (FE_INVALID) == 0);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+  ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /* Test setting just one exception flag: FE_OVERFLOW.  */
+  ASSERT (feclearexcept (FE_ALL_EXCEPT) == 0);
+  ASSERT (fesetexcept (FE_OVERFLOW) == 0);
+  ASSERT (fetestexcept (FE_ALL_EXCEPT) == FE_OVERFLOW);
+  ASSERT (fetestexcept (FE_INVALID) == 0);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == 0);
+  ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /* Test setting just one exception flag: FE_UNDERFLOW.  */
+  ASSERT (feclearexcept (FE_ALL_EXCEPT) == 0);
+  ASSERT (fesetexcept (FE_UNDERFLOW) == 0);
+  ASSERT (fetestexcept (FE_ALL_EXCEPT) == FE_UNDERFLOW);
+  ASSERT (fetestexcept (FE_INVALID) == 0);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == 0);
+  ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /* Test setting just one exception flag: FE_INEXACT.  */
+  ASSERT (feclearexcept (FE_ALL_EXCEPT) == 0);
+  ASSERT (fesetexcept (FE_INEXACT) == 0);
+  ASSERT (fetestexcept (FE_ALL_EXCEPT) == FE_INEXACT);
+  ASSERT (fetestexcept (FE_INVALID) == 0);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == 0);
+  ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
+  ASSERT (fetestexcept (FE_INEXACT) == FE_INEXACT);
+
+
+  return 0;
+}
diff --git a/tests/test-fenv-except-tracking-5.c b/tests/test-fenv-except-tracking-5.c
new file mode 100644 (file)
index 0000000..0efb5e6
--- /dev/null
@@ -0,0 +1,79 @@
+/* Test of tracking of floating-point exceptions.
+   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 <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 fesetexcept() does not trigger a trap.  */
+
+static volatile double a, b;
+static volatile long double al, bl;
+
+int
+main ()
+{
+  /* Clear FE_INVALID exceptions from past operations.  */
+  feclearexcept (FE_INVALID);
+
+  /* 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 = fesetexcept (FE_INVALID);
+  /* On older i386 and on PowerPC, there is no way to implement
+     fesetexcept() such that it does not trigger a trap.  fesetexcept()
+     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 or fpsetmask or fp_enable not available\n", stderr);
+  return 77;
+}
+
+#endif