usleep tests: Avoid failure due to known Cygwin 3.5.3 bug.
[gnulib.git] / tests / test-snan-2.c
blobbdc398833e43347505223334a6c49a7252fd0590
1 /* Tests of signalling not-a-number.
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 "snan.h"
24 #include <stdio.h>
26 #include "fpe-trapping.h"
28 #if HAVE_FPE_TRAPPING
30 # include <fenv.h>
32 # include "macros.h"
34 float volatile resultf;
35 double volatile resultd;
36 long double volatile resultl;
38 int
39 main (int argc, char *argv[])
41 /* Fetch the NaN values before we start watching out for FE_INVALID
42 exceptions, because the division 0.0 / 0.0 itself also raises an
43 FE_INVALID exception.
44 The use of 'volatile' prevents the compiler from doing constant-folding
45 optimizations on these values. An alternative, for GCC only, would be
46 the command-line option '-fsignaling-nans'. */
47 _GL_UNUSED float volatile nanf = SNaNf ();
48 _GL_UNUSED double volatile nand = SNaNd ();
49 _GL_UNUSED long double volatile nanl = SNaNl ();
51 /* Check that the values are really signalling. */
53 /* Clear FE_INVALID exceptions from past operations. */
54 feclearexcept (FE_INVALID);
56 /* An FE_INVALID exception shall trigger a SIGFPE signal, which by default
57 terminates the program. */
58 if (sigfpe_on_invalid () < 0)
60 fputs ("Skipping test: trapping floating-point exceptions are not supported on this machine.\n", stderr);
61 return 77;
64 if (argc > 1)
65 switch (argv[1][0])
67 case 'f':
68 /* This test does not work on 32-bit x86 processors, as well as
69 on x86_64 processors with CC="gcc -mfpmath=387", because loading
70 SNaNf() into a 387 FPU register already converted it to a quiet NaN.
71 See <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
72 for details. */
73 #if !((defined __i386 || defined _M_IX86) \
74 || ((defined __x86_64__ || defined _M_X64) && __FLT_EVAL_METHOD__ == 2))
75 /* This test does not work on AIX 7.1 with the xlc compiler, even with
76 the compiler options -qfloat=fenv -qfloat=nans -qfloat=spnans. */
77 #if !(defined _AIX && defined __xlC__)
78 resultf = nanf + 42.0f;
79 #else
80 fputs ("Skipping test: known failure on this platform with this compiler\n", stderr);
81 return 77;
82 #endif
83 #else
84 fputs ("Skipping test: known failure on this platform\n", stderr);
85 return 77;
86 #endif
87 break;
89 case 'd':
90 /* This test does not work on 32-bit x86 processors, as well as
91 on x86_64 processors with CC="gcc -mfpmath=387", because loading
92 SNaNd() into a 387 FPU register already converted it to a quiet NaN.
93 See <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
94 for details. */
95 #if !((defined __i386 || defined _M_IX86) \
96 || ((defined __x86_64__ || defined _M_X64) && __FLT_EVAL_METHOD__ == 2))
97 resultd = nand + 42.0;
98 #else
99 fputs ("Skipping test: known failure on this platform\n", stderr);
100 return 77;
101 #endif
102 break;
104 case 'l':
105 /* This test does not work on Linux/alpha with glibc 2.7. But it
106 works with glibc 2.36. Cause unknown.
107 This test does not work on Linux/loongarch64 with glibc 2.37.
108 Cause unknown.
109 This test does not work on eglibc 2.13/mips64
110 (bug in libc function __addtf3).
111 This test does not work on FreeBSD/arm64 and OpenBSD/mips64
112 (bug in libc function __addtf3).
113 This test does not work on FreeBSD/sparc64 and NetBSD/sparc64
114 (bug in libc function _Qp_add).
115 This test does not work on Cygwin 2.9.0/i386. Cause unknown.
116 This test does not work on MSVC/i386, because of the general IA-32
117 problem (see above) and 'long double' == 'double'. */
118 #if !((__GLIBC__ == 2 && __GLIBC_MINOR__ < 36 && defined __alpha__) \
119 || (__GLIBC__ >= 2 && defined __loongarch__) \
120 || (((__GLIBC__ == 2 && __GLIBC_MINOR__ < 19 && defined __mips64) \
121 || ((defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__) && (defined __aarch64__ || defined __mips64__ || defined __sparc__))) \
122 && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE) \
123 || (defined __CYGWIN__ && defined __i386) \
124 || (((defined __i386 || defined _M_IX86) \
125 || ((defined __x86_64__ || defined _M_X64) && __FLT_EVAL_METHOD__ == 2)) \
126 && HAVE_SAME_LONG_DOUBLE_AS_DOUBLE))
127 resultl = nanl + 42.0L;
128 #else
129 fputs ("Skipping test: known failure on this platform\n", stderr);
130 return 77;
131 #endif
132 break;
134 default:
135 break;
138 return test_exit_status;
141 #else
143 /* No HAVE_FPE_TRAPPING available.
144 We could use the various alternative approaches from
145 libgfortran/config/fpu-*.h, but that's not worth it. */
148 main ()
150 fputs ("Skipping test: feenableexcept not available\n", stderr);
151 return 77;
154 #endif