summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/ieeefp/except/except.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libc/ieeefp/except/except.c')
-rw-r--r--src/regress/lib/libc/ieeefp/except/except.c156
1 files changed, 89 insertions, 67 deletions
diff --git a/src/regress/lib/libc/ieeefp/except/except.c b/src/regress/lib/libc/ieeefp/except/except.c
index 0ffdcdd468..0f25cadefc 100644
--- a/src/regress/lib/libc/ieeefp/except/except.c
+++ b/src/regress/lib/libc/ieeefp/except/except.c
@@ -1,21 +1,47 @@
1/* $OpenBSD: except.c,v 1.11 2007/10/22 21:07:10 miod Exp $ */
2
3#include <sys/types.h>
4#include <unistd.h>
1#include <stdio.h> 5#include <stdio.h>
6#include <stdlib.h>
2#include <signal.h> 7#include <signal.h>
3#include <assert.h> 8#include <assert.h>
4#include <ieeefp.h> 9#include <ieeefp.h>
5#include <float.h> 10#include <float.h>
11#include <err.h>
6 12
7void sigfpe(); 13volatile sig_atomic_t signal_status;
8volatile sig_atomic_t signal_cought;
9 14
10static volatile const double one = 1.0; 15volatile const double one = 1.0;
11static volatile const double zero = 0.0; 16volatile const double zero = 0.0;
12static volatile const double huge = DBL_MAX; 17volatile const double huge = DBL_MAX;
13static volatile const double tiny = DBL_MIN; 18volatile const double tiny = DBL_MIN;
14 19
15main() 20void
21sigfpe(int sig, siginfo_t *si, void *v)
16{ 22{
23 char buf[132];
24
25 if (si) {
26 snprintf(buf, sizeof(buf), "sigfpe: addr=%p, code=%d\n",
27 si->si_addr, si->si_code);
28 write(1, buf, strlen(buf));
29 }
30 _exit(signal_status);
31}
32
33
34int
35main(int argc, char *argv[])
36{
37 struct sigaction sa;
17 volatile double x; 38 volatile double x;
18 39
40 if (argc != 2) {
41 fprintf(stderr, "usage: %s condition\n", argv[0]);
42 exit(1);
43 }
44
19 /* 45 /*
20 * check to make sure that all exceptions are masked and 46 * check to make sure that all exceptions are masked and
21 * that the accumulated exception status is clear. 47 * that the accumulated exception status is clear.
@@ -23,65 +49,61 @@ main()
23 assert(fpgetmask() == 0); 49 assert(fpgetmask() == 0);
24 assert(fpgetsticky() == 0); 50 assert(fpgetsticky() == 0);
25 51
26 /* set up signal handler */ 52 memset(&sa, 0, sizeof(sa));
27 signal (SIGFPE, sigfpe); 53 sa.sa_sigaction = sigfpe;
28 signal_cought = 0; 54 sa.sa_flags = SA_SIGINFO;
29 55 sigaction(SIGFPE, &sa, NULL);
30 /* trip divide by zero */ 56 signal_status = 1;
31 x = one / zero;
32 assert (fpgetsticky() & FP_X_DZ);
33 assert (signal_cought == 0);
34 fpsetsticky(0);
35
36 /* trip invalid operation */
37 x = zero / zero;
38 assert (fpgetsticky() & FP_X_INV);
39 assert (signal_cought == 0);
40 fpsetsticky(0);
41
42 /* trip overflow */
43 x = huge * huge;
44 assert (fpgetsticky() & FP_X_OFL);
45 assert (signal_cought == 0);
46 fpsetsticky(0);
47
48 /* trip underflow */
49 x = tiny * tiny;
50 assert (fpgetsticky() & FP_X_UFL);
51 assert (signal_cought == 0);
52 fpsetsticky(0);
53
54#if 0
55 /* unmask and then trip divide by zero */
56 fpsetmask(FP_X_DZ);
57 x = one / zero;
58 assert (signal_cought == 1);
59 signal_cought = 0;
60
61 /* unmask and then trip invalid operation */
62 fpsetmask(FP_X_INV);
63 x = zero / zero;
64 assert (signal_cought == 1);
65 signal_cought = 0;
66
67 /* unmask and then trip overflow */
68 fpsetmask(FP_X_OFL);
69 x = huge * huge;
70 assert (signal_cought == 1);
71 signal_cought = 0;
72
73 /* unmask and then trip underflow */
74 fpsetmask(FP_X_UFL);
75 x = tiny * tiny;
76 assert (signal_cought == 1);
77 signal_cought = 0;
78#endif
79
80 exit(0);
81}
82 57
83void 58 if (strcmp(argv[1], "fltdiv") == 0) {
84sigfpe() 59 /* trip divide by zero */
85{ 60 x = one / zero;
86 signal_cought = 1; 61 assert(fpgetsticky() & FP_X_DZ);
62 fpsetsticky(0);
63
64 /* and now unmask to get a signal */
65 signal_status = 0;
66 fpsetmask(FP_X_DZ);
67 x = one / zero;
68 } else if (strcmp(argv[1], "fltinv") == 0) {
69 /* trip invalid operation */
70 x = zero / zero;
71 assert(fpgetsticky() & FP_X_INV);
72 fpsetsticky(0);
73
74 /* and now unmask to get a signal */
75 signal_status = 0;
76 fpsetmask(FP_X_INV);
77 x = zero / zero;
78 } else if (strcmp(argv[1], "fltovf") == 0) {
79 /* trip overflow */
80 x = huge * huge;
81 assert(fpgetsticky() & FP_X_OFL);
82 fpsetsticky(0);
83
84 /* and now unmask to get a signal */
85 signal_status = 0;
86 fpsetmask(FP_X_OFL);
87 x = huge * huge;
88 } else if (strcmp(argv[1], "fltund") == 0) {
89 /* trip underflow */
90 x = tiny * tiny;
91 assert(fpgetsticky() & FP_X_UFL);
92 fpsetsticky(0);
93
94 /* and now unmask to get a signal */
95 signal_status = 0;
96 fpsetmask(FP_X_UFL);
97 x = tiny * tiny;
98 } else {
99 errx(1, "unrecognized condition %s", argv[1]);
100 }
101
102 /*
103 * attempt to trigger the exception on machines where
104 * floating-point exceptions are deferred.
105 */
106 x = one * one;
107
108 errx(1, "signal wasn't caught");
87} 109}