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.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/regress/lib/libc/ieeefp/except/except.c b/src/regress/lib/libc/ieeefp/except/except.c
new file mode 100644
index 0000000000..1d11877777
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/except/except.c
@@ -0,0 +1,107 @@
1/* $OpenBSD: except.c,v 1.10 2006/05/15 14:00:22 kettenis Exp $ */
2
3#include <sys/types.h>
4#include <unistd.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <signal.h>
8#include <assert.h>
9#include <ieeefp.h>
10#include <float.h>
11#include <err.h>
12
13volatile sig_atomic_t signal_status;
14
15volatile const double one = 1.0;
16volatile const double zero = 0.0;
17volatile const double huge = DBL_MAX;
18volatile const double tiny = DBL_MIN;
19
20void
21sigfpe(int sig, siginfo_t *si, void *v)
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;
38 volatile double x;
39
40 if (argc != 2) {
41 fprintf(stderr, "usage: %s condition\n", argv[0]);
42 exit(1);
43 }
44
45 /*
46 * check to make sure that all exceptions are masked and
47 * that the accumulated exception status is clear.
48 */
49 assert(fpgetmask() == 0);
50 assert(fpgetsticky() == 0);
51
52 memset(&sa, 0, sizeof(sa));
53 sa.sa_sigaction = sigfpe;
54 sa.sa_flags = SA_SIGINFO;
55 sigaction(SIGFPE, &sa, NULL);
56 signal_status = 1;
57
58 /* trip divide by zero */
59 x = one / zero;
60 assert(fpgetsticky() & FP_X_DZ);
61 fpsetsticky(0);
62
63 /* trip invalid operation */
64 x = zero / zero;
65 assert(fpgetsticky() & FP_X_INV);
66 fpsetsticky(0);
67
68 /* trip overflow */
69 x = huge * huge;
70 assert(fpgetsticky() & FP_X_OFL);
71 fpsetsticky(0);
72
73 /* trip underflow */
74 x = tiny * tiny;
75 assert(fpgetsticky() & FP_X_UFL);
76 fpsetsticky(0);
77
78 signal_status = 0;
79
80 if (strcmp(argv[1], "fltdiv") == 0) {
81 /* unmask and then trip divide by zero */
82 fpsetmask(FP_X_DZ);
83 x = one / zero;
84 } else if (strcmp(argv[1], "fltinv") == 0) {
85 /* unmask and then trip invalid operation */
86 fpsetmask(FP_X_INV);
87 x = zero / zero;
88 } else if (strcmp(argv[1], "fltovf") == 0) {
89 /* unmask and then trip overflow */
90 fpsetmask(FP_X_OFL);
91 x = huge * huge;
92 } else if (strcmp(argv[1], "fltund") == 0) {
93 /* unmask and then trip underflow */
94 fpsetmask(FP_X_UFL);
95 x = tiny * tiny;
96 } else {
97 errx(1, "unrecognized condition %s", argv[1]);
98 }
99
100 /*
101 * attempt to trigger the exception on machines where
102 * floating-point exceptions are deferred.
103 */
104 x = one * one;
105
106 errx(1, "signal wasn't caught");
107}