1 /* Raise given exceptions.
2    Copyright (C) 1997-2025 Free Software Foundation, Inc.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <fenv.h>
19 #include <float.h>
20 #include <math.h>
21 #include "math-barriers.h"
22 
23 int
feraiseexcept(int excepts)24 feraiseexcept (int excepts)
25 {
26   static const struct {
27     double zero, one, max, min, pi;
28   } c = {
29     0.0, 1.0, DBL_MAX, DBL_MIN, M_PI
30   };
31   double d;
32 
33   /* Raise exceptions represented by EXPECTS.  But we must raise only
34      one signal at a time.  It is important the if the overflow/underflow
35      exception and the inexact exception are given at the same time,
36      the overflow/underflow exception follows the inexact exception.  */
37 
38   /* First: invalid exception.  */
39   if ((FE_INVALID & excepts) != 0)
40     {
41       /* One example of an invalid operation is 0/0.  */
42       __asm__ ("" : "=e" (d) : "0" (c.zero));
43       d /= c.zero;
44       math_force_eval (d);
45     }
46 
47   /* Next: division by zero.  */
48   if ((FE_DIVBYZERO & excepts) != 0)
49     {
50       __asm__ ("" : "=e" (d) : "0" (c.one));
51       d /= c.zero;
52       math_force_eval (d);
53     }
54 
55   /* Next: overflow.  */
56   if ((FE_OVERFLOW & excepts) != 0)
57     {
58       __asm__ ("" : "=e" (d) : "0" (c.max));
59       d *= d;
60       math_force_eval (d);
61     }
62 
63   /* Next: underflow.  */
64   if ((FE_UNDERFLOW & excepts) != 0)
65     {
66       __asm__ ("" : "=e" (d) : "0" (c.min));
67       d *= d;
68       math_force_eval (d);
69     }
70 
71   /* Last: inexact.  */
72   if ((FE_INEXACT & excepts) != 0)
73     {
74       __asm__ ("" : "=e" (d) : "0" (c.one));
75       d /= c.pi;
76       math_force_eval (d);
77     }
78 
79   /* Success.  */
80   return 0;
81 }
82