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