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.c109
1 files changed, 109 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..0f25cadefc
--- /dev/null
+++ b/src/regress/lib/libc/ieeefp/except/except.c
@@ -0,0 +1,109 @@
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>
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 if (strcmp(argv[1], "fltdiv") == 0) {
59 /* trip divide by zero */
60 x = one / zero;
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");
109}