Move "-sNaN" value into a separate variable.
[platform/upstream/glibc.git] / math / test-snan.c
1 /* Test signaling NaNs in isnan, isinf, and similar functions.
2    Copyright (C) 2008-2013 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Andreas Jaeger <aj@suse.de>, 2005.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #define _GNU_SOURCE 1
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/time.h>
24 #include <string.h>
25 #include <math.h>
26 #include <float.h>
27 #include <fenv.h>
28 #include <signal.h>
29 #include <setjmp.h>
30 #include <errno.h>
31
32 int dest_offset;
33 char *dest_address;
34 double  value = 123.456;
35 double  zero = 0.0;
36
37 static sigjmp_buf sigfpe_buf;
38
39 typedef long double ldouble;
40
41
42 void
43 myFPsighandler(int signal,
44              siginfo_t *info,
45              void *context)
46 {
47   siglongjmp(sigfpe_buf, 0);
48 }
49
50 int
51 set_sigaction_FP(void)
52 {
53     struct sigaction sa;
54     /* register RT signal handler via sigaction */
55     sa.sa_flags = SA_SIGINFO;
56     sa.sa_sigaction = &myFPsighandler;
57     sigemptyset(&sa.sa_mask);
58     sigaction(SIGFPE, &sa, NULL);
59
60     return 0;
61 }
62
63 int
64 remove_sigaction_FP(void)
65 {
66     struct sigaction sa;
67     /* restore default RT signal handler via sigaction */
68     sa.sa_flags = SA_SIGINFO;
69     sa.sa_handler = SIG_DFL;
70     sigemptyset(&sa.sa_mask);
71     sigaction(SIGFPE, &sa, NULL);
72
73     return 0;
74 }
75
76 static int errors = 0;
77
78 static void
79 check (const char *testname, int result)
80 {
81   if (!result) {
82     printf ("Failure: %s\n", testname);
83     errors++;
84   }
85 }
86
87 #define TEST_FUNC(NAME, FLOAT, SUFFIX)                                        \
88 static void                                                                   \
89 NAME (void)                                                                   \
90 {                                                                             \
91   /* Variables are declared volatile to forbid some compiler                  \
92      optimizations.  */                                                       \
93   volatile FLOAT Inf_var, qNaN_var, zero_var, one_var;                        \
94   /* A sNaN is only guaranteed to be representable in variables with */       \
95   /* static (or thread-local) storage duration.  */                           \
96   static volatile FLOAT sNaN_var = __builtin_nans ## SUFFIX ("");             \
97   static volatile FLOAT minus_sNaN_var = -__builtin_nans ## SUFFIX ("");      \
98   fenv_t saved_fenv;                                                          \
99                                                                               \
100   zero_var = 0.0;                                                             \
101   one_var = 1.0;                                                              \
102   qNaN_var = __builtin_nan ## SUFFIX ("");                                    \
103   Inf_var = one_var / zero_var;                                               \
104                                                                               \
105   (void) &zero_var;                                                           \
106   (void) &one_var;                                                            \
107   (void) &qNaN_var;                                                           \
108   (void) &sNaN_var;                                                           \
109   (void) &minus_sNaN_var;                                                     \
110   (void) &Inf_var;                                                            \
111                                                                               \
112   set_sigaction_FP ();                                                        \
113   fegetenv(&saved_fenv);                                                      \
114                                                                               \
115   feclearexcept(FE_ALL_EXCEPT);                                               \
116   feenableexcept (FE_ALL_EXCEPT);                                             \
117   if (sigsetjmp(sigfpe_buf, 0))                                               \
118     {                                                                         \
119       printf (#FLOAT " isnan (qNaN) raised SIGFPE\n");                        \
120       errors++;                                                               \
121     } else {                                                                  \
122       check (#FLOAT " isnan (qNaN)", isnan (qNaN_var));                       \
123     }                                                                         \
124                                                                               \
125   feclearexcept(FE_ALL_EXCEPT);                                               \
126   feenableexcept (FE_ALL_EXCEPT);                                             \
127   if (sigsetjmp(sigfpe_buf, 0))                                               \
128     {                                                                         \
129       printf (#FLOAT " isnan (-qNaN) raised SIGFPE\n");                       \
130       errors++;                                                               \
131     } else {                                                                  \
132       check (#FLOAT " isnan (-qNaN)", isnan (-qNaN_var));                     \
133     }                                                                         \
134                                                                               \
135   feclearexcept(FE_ALL_EXCEPT);                                               \
136   feenableexcept (FE_ALL_EXCEPT);                                             \
137   if (sigsetjmp(sigfpe_buf, 0))                                               \
138     {                                                                         \
139       printf (#FLOAT " isnan (sNaN) raised SIGFPE\n");                        \
140       errors++;                                                               \
141     } else {                                                                  \
142       check (#FLOAT " isnan (sNaN)", isnan (sNaN_var));                       \
143     }                                                                         \
144                                                                               \
145   feclearexcept(FE_ALL_EXCEPT);                                               \
146   feenableexcept (FE_ALL_EXCEPT);                                             \
147   if (sigsetjmp(sigfpe_buf, 0))                                               \
148     {                                                                         \
149       printf (#FLOAT " isnan (-sNaN) raised SIGFPE\n");                       \
150       errors++;                                                               \
151     } else {                                                                  \
152       check (#FLOAT " isnan (-sNaN)", isnan (minus_sNaN_var));                \
153     }                                                                         \
154                                                                               \
155   feclearexcept(FE_ALL_EXCEPT);                                               \
156   feenableexcept (FE_ALL_EXCEPT);                                             \
157   if (sigsetjmp(sigfpe_buf, 0))                                               \
158     {                                                                         \
159       printf (#FLOAT " isinf (qNaN) raised SIGFPE\n");                        \
160       errors++;                                                               \
161     } else {                                                                  \
162       check (#FLOAT " isinf (qNaN)", !isinf (qNaN_var));                      \
163     }                                                                         \
164                                                                               \
165   feclearexcept(FE_ALL_EXCEPT);                                               \
166   feenableexcept (FE_ALL_EXCEPT);                                             \
167   if (sigsetjmp(sigfpe_buf, 0))                                               \
168     {                                                                         \
169       printf (#FLOAT " isinf (-qNaN) raised SIGFPE\n");                       \
170       errors++;                                                               \
171     } else {                                                                  \
172       check (#FLOAT " isinf (-qNaN)", !isinf (-qNaN_var));                    \
173     }                                                                         \
174                                                                               \
175   feclearexcept(FE_ALL_EXCEPT);                                               \
176   feenableexcept (FE_ALL_EXCEPT);                                             \
177   if (sigsetjmp(sigfpe_buf, 0))                                               \
178     {                                                                         \
179       printf (#FLOAT " isinf (sNaN) raised SIGFPE\n");                        \
180       errors++;                                                               \
181     } else {                                                                  \
182       check (#FLOAT " isinf (sNaN)", !isinf (sNaN_var));                      \
183     }                                                                         \
184                                                                               \
185   feclearexcept(FE_ALL_EXCEPT);                                               \
186   feenableexcept (FE_ALL_EXCEPT);                                             \
187   if (sigsetjmp(sigfpe_buf, 0))                                               \
188     {                                                                         \
189       printf (#FLOAT " isinf (-sNaN) raised SIGFPE\n");                       \
190       errors++;                                                               \
191     } else {                                                                  \
192       check (#FLOAT " isinf (-sNaN)", !isinf (minus_sNaN_var));               \
193     }                                                                         \
194                                                                               \
195   feclearexcept(FE_ALL_EXCEPT);                                               \
196   feenableexcept (FE_ALL_EXCEPT);                                             \
197   if (sigsetjmp(sigfpe_buf, 0))                                               \
198     {                                                                         \
199       printf (#FLOAT " isfinite (qNaN) raised SIGFPE\n");                     \
200       errors++;                                                               \
201     } else {                                                                  \
202       check (#FLOAT " isfinite (qNaN)", !isfinite (qNaN_var));                \
203     }                                                                         \
204                                                                               \
205   feclearexcept(FE_ALL_EXCEPT);                                               \
206   feenableexcept (FE_ALL_EXCEPT);                                             \
207   if (sigsetjmp(sigfpe_buf, 0))                                               \
208     {                                                                         \
209       printf (#FLOAT " isfinite (-qNaN) raised SIGFPE\n");                    \
210       errors++;                                                               \
211     } else {                                                                  \
212       check (#FLOAT " isfinite (-qNaN)", !isfinite (-qNaN_var));              \
213     }                                                                         \
214                                                                               \
215   feclearexcept(FE_ALL_EXCEPT);                                               \
216   feenableexcept (FE_ALL_EXCEPT);                                             \
217   if (sigsetjmp(sigfpe_buf, 0))                                               \
218     {                                                                         \
219       printf (#FLOAT " isfinite (sNaN) raised SIGFPE\n");                     \
220       errors++;                                                               \
221     } else {                                                                  \
222       check (#FLOAT " isfinite (sNaN)", !isfinite (sNaN_var));                \
223     }                                                                         \
224                                                                               \
225   feclearexcept(FE_ALL_EXCEPT);                                               \
226   feenableexcept (FE_ALL_EXCEPT);                                             \
227   if (sigsetjmp(sigfpe_buf, 0))                                               \
228     {                                                                         \
229       printf (#FLOAT " isfinite (-sNaN) raised SIGFPE\n");                    \
230       errors++;                                                               \
231     } else {                                                                  \
232       check (#FLOAT " isfinite (-sNaN)", !isfinite (minus_sNaN_var));         \
233     }                                                                         \
234                                                                               \
235   feclearexcept(FE_ALL_EXCEPT);                                               \
236   feenableexcept (FE_ALL_EXCEPT);                                             \
237   if (sigsetjmp(sigfpe_buf, 0))                                               \
238     {                                                                         \
239       printf (#FLOAT " isnormal (qNaN) raised SIGFPE\n");                     \
240       errors++;                                                               \
241     } else {                                                                  \
242       check (#FLOAT " isnormal (qNaN)", !isnormal (qNaN_var));                \
243     }                                                                         \
244                                                                               \
245   feclearexcept(FE_ALL_EXCEPT);                                               \
246   feenableexcept (FE_ALL_EXCEPT);                                             \
247   if (sigsetjmp(sigfpe_buf, 0))                                               \
248     {                                                                         \
249       printf (#FLOAT " isnormal (-qNaN) raised SIGFPE\n");                    \
250       errors++;                                                               \
251     } else {                                                                  \
252       check (#FLOAT " isnormal (-qNaN)", !isnormal (-qNaN_var));              \
253     }                                                                         \
254                                                                               \
255   feclearexcept(FE_ALL_EXCEPT);                                               \
256   feenableexcept (FE_ALL_EXCEPT);                                             \
257   if (sigsetjmp(sigfpe_buf, 0))                                               \
258     {                                                                         \
259       printf (#FLOAT " isnormal (sNaN) isnormal SIGFPE\n");                   \
260       errors++;                                                               \
261     } else {                                                                  \
262       check (#FLOAT " isnormal (sNaN)", !isnormal (sNaN_var));                \
263     }                                                                         \
264                                                                               \
265   feclearexcept(FE_ALL_EXCEPT);                                               \
266   feenableexcept (FE_ALL_EXCEPT);                                             \
267   if (sigsetjmp(sigfpe_buf, 0))                                               \
268     {                                                                         \
269       printf (#FLOAT " isnormal (-sNaN) raised SIGFPE\n");                    \
270       errors++;                                                               \
271     } else {                                                                  \
272       check (#FLOAT " isnormal (-sNaN)", !isnormal (minus_sNaN_var));         \
273     }                                                                         \
274                                                                               \
275   feclearexcept(FE_ALL_EXCEPT);                                               \
276   feenableexcept (FE_ALL_EXCEPT);                                             \
277   if (sigsetjmp(sigfpe_buf, 0))                                               \
278     {                                                                         \
279       printf (#FLOAT " fpclassify (qNaN) raised SIGFPE\n");                   \
280       errors++;                                                               \
281     } else {                                                                  \
282       check (#FLOAT " fpclassify (qNaN)", (fpclassify (qNaN_var)==FP_NAN));   \
283     }                                                                         \
284                                                                               \
285   feclearexcept(FE_ALL_EXCEPT);                                               \
286   feenableexcept (FE_ALL_EXCEPT);                                             \
287   if (sigsetjmp(sigfpe_buf, 0))                                               \
288     {                                                                         \
289       printf (#FLOAT " fpclassify (-qNaN) raised SIGFPE\n");                  \
290       errors++;                                                               \
291     } else {                                                                  \
292       check (#FLOAT " fpclassify (-qNaN)", (fpclassify (-qNaN_var)==FP_NAN)); \
293     }                                                                         \
294                                                                               \
295   feclearexcept(FE_ALL_EXCEPT);                                               \
296   feenableexcept (FE_ALL_EXCEPT);                                             \
297   if (sigsetjmp(sigfpe_buf, 0))                                               \
298     {                                                                         \
299       printf (#FLOAT " fpclassify (sNaN) isnormal SIGFPE\n");                 \
300       errors++;                                                               \
301     } else {                                                                  \
302       check (#FLOAT " fpclassify (sNaN)", fpclassify (sNaN_var) == FP_NAN);   \
303     }                                                                         \
304                                                                               \
305   feclearexcept(FE_ALL_EXCEPT);                                               \
306   feenableexcept (FE_ALL_EXCEPT);                                             \
307   if (sigsetjmp(sigfpe_buf, 0))                                               \
308     {                                                                         \
309       printf (#FLOAT " fpclassify (-sNaN) raised SIGFPE\n");                  \
310       errors++;                                                               \
311     } else {                                                                  \
312       check (#FLOAT " fpclassify (-sNaN)",                                    \
313              fpclassify (minus_sNaN_var) == FP_NAN);                          \
314     }                                                                         \
315                                                                               \
316   fesetenv(&saved_fenv); /* restore saved fenv */                             \
317   remove_sigaction_FP();                                                      \
318 }
319
320 TEST_FUNC (float_test, float, f)
321 TEST_FUNC (double_test, double, )
322 #ifndef NO_LONG_DOUBLE
323 TEST_FUNC (ldouble_test, ldouble, l)
324 #endif
325
326 static int
327 do_test (void)
328 {
329   float_test();
330   double_test();
331 #ifndef NO_LONG_DOUBLE
332   ldouble_test();
333 #endif
334
335   return errors != 0;
336 }
337
338 #define TEST_FUNCTION do_test ()
339 #include "../test-skeleton.c"