xref: /openbsd-src/regress/lib/libc/ieeefp/except/except.c (revision 07ea8d1515ffde9f9d310504e9c8852d6bf7074c)
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 int
16 main()
17 {
18 	volatile double x;
19 
20 	/*
21 	 * check to make sure that all exceptions are masked and
22 	 * that the accumulated exception status is clear.
23  	 */
24 	assert(fpgetmask() == 0);
25 	assert(fpgetsticky() == 0);
26 
27 	/* set up signal handler */
28 	signal (SIGFPE, sigfpe);
29 	signal_cought = 0;
30 
31 	/* trip divide by zero */
32 	x = one / zero;
33 	assert (fpgetsticky() & FP_X_DZ);
34 	assert (signal_cought == 0);
35 	fpsetsticky(0);
36 
37 	/* trip invalid operation */
38 	x = zero / zero;
39 	assert (fpgetsticky() & FP_X_INV);
40 	assert (signal_cought == 0);
41 	fpsetsticky(0);
42 
43 	/* trip overflow */
44 	x = huge * huge;
45 	assert (fpgetsticky() & FP_X_OFL);
46 	assert (signal_cought == 0);
47 	fpsetsticky(0);
48 
49 	/* trip underflow */
50 	x = tiny * tiny;
51 	assert (fpgetsticky() & FP_X_UFL);
52 	assert (signal_cought == 0);
53 	fpsetsticky(0);
54 
55 #if 0
56 	/* unmask and then trip divide by zero */
57 	fpsetmask(FP_X_DZ);
58 	x = one / zero;
59 	assert (signal_cought == 1);
60 	signal_cought = 0;
61 
62 	/* unmask and then trip invalid operation */
63 	fpsetmask(FP_X_INV);
64 	x = zero / zero;
65 	assert (signal_cought == 1);
66 	signal_cought = 0;
67 
68 	/* unmask and then trip overflow */
69 	fpsetmask(FP_X_OFL);
70 	x = huge * huge;
71 	assert (signal_cought == 1);
72 	signal_cought = 0;
73 
74 	/* unmask and then trip underflow */
75 	fpsetmask(FP_X_UFL);
76 	x = tiny * tiny;
77 	assert (signal_cought == 1);
78 	signal_cought = 0;
79 #endif
80 
81 	exit(0);
82 }
83 
84 void
85 sigfpe()
86 {
87 	signal_cought = 1;
88 }
89