xref: /openbsd-src/regress/lib/libc/ieeefp/except/except.c (revision df930be708d50e9715f173caa26ffe1b7599b157)
1 #include <stdio.h>
2 #include <signal.h>
3 #include <assert.h>
4 #include <ieeefp.h>
5 #include <float.h>
6 
7 void sigfpe();
8 volatile sig_atomic_t signal_cought;
9 
10 static volatile const double one  = 1.0;
11 static volatile const double zero = 0.0;
12 static volatile const double huge = DBL_MAX;
13 static volatile const double tiny = DBL_MIN;
14 
15 main()
16 {
17 	volatile double x;
18 
19 	/*
20 	 * check to make sure that all exceptions are masked and
21 	 * that the accumulated exception status is clear.
22  	 */
23 	assert(fpgetmask() == 0);
24 	assert(fpgetsticky() == 0);
25 
26 	/* set up signal handler */
27 	signal (SIGFPE, sigfpe);
28 	signal_cought = 0;
29 
30 	/* trip divide by zero */
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 
83 void
84 sigfpe()
85 {
86 	signal_cought = 1;
87 }
88