1 //===-- Unittests for feclearexcept, feraiseexcept and fetestexpect -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/fenv/feclearexcept.h"
10 #include "src/fenv/feraiseexcept.h"
11 #include "src/fenv/fetestexcept.h"
12 
13 #include "utils/FPUtil/FEnvUtils.h"
14 #include "utils/UnitTest/Test.h"
15 
16 #include <fenv.h>
17 
TEST(LlvmLibcExceptionStatusTest,RaiseAndTest)18 TEST(LlvmLibcExceptionStatusTest, RaiseAndTest) {
19   // This test raises a set of exceptions and checks that the exception
20   // status flags are updated. The intention is really not to invoke the
21   // exception handler. Hence, we will disable all exceptions at the
22   // beginning.
23   __llvm_libc::fputil::disableExcept(FE_ALL_EXCEPT);
24 
25   int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
26                    FE_UNDERFLOW};
27 
28   constexpr int allExcepts =
29       FE_DIVBYZERO | FE_INVALID | FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW;
30 
31   for (int e : excepts) {
32     int r = __llvm_libc::feraiseexcept(e);
33     ASSERT_EQ(r, 0);
34     int s = __llvm_libc::fetestexcept(e);
35     ASSERT_EQ(s, e);
36 
37     r = __llvm_libc::feclearexcept(e);
38     ASSERT_EQ(r, 0);
39     s = __llvm_libc::fetestexcept(e);
40     ASSERT_EQ(s, 0);
41   }
42 
43   for (int e1 : excepts) {
44     for (int e2 : excepts) {
45       int e = e1 | e2;
46       int r = __llvm_libc::feraiseexcept(e);
47       ASSERT_EQ(r, 0);
48       int s = __llvm_libc::fetestexcept(e);
49       ASSERT_EQ(s, e);
50 
51       r = __llvm_libc::feclearexcept(e);
52       ASSERT_EQ(r, 0);
53       s = __llvm_libc::fetestexcept(e);
54       ASSERT_EQ(s, 0);
55     }
56   }
57 
58   for (int e1 : excepts) {
59     for (int e2 : excepts) {
60       for (int e3 : excepts) {
61         int e = e1 | e2 | e3;
62         int r = __llvm_libc::feraiseexcept(e);
63         ASSERT_EQ(r, 0);
64         int s = __llvm_libc::fetestexcept(e);
65         ASSERT_EQ(s, e);
66 
67         r = __llvm_libc::feclearexcept(e);
68         ASSERT_EQ(r, 0);
69         s = __llvm_libc::fetestexcept(e);
70         ASSERT_EQ(s, 0);
71       }
72     }
73   }
74 
75   for (int e1 : excepts) {
76     for (int e2 : excepts) {
77       for (int e3 : excepts) {
78         for (int e4 : excepts) {
79           int e = e1 | e2 | e3 | e4;
80           int r = __llvm_libc::feraiseexcept(e);
81           ASSERT_EQ(r, 0);
82           int s = __llvm_libc::fetestexcept(e);
83           ASSERT_EQ(s, e);
84 
85           r = __llvm_libc::feclearexcept(e);
86           ASSERT_EQ(r, 0);
87           s = __llvm_libc::fetestexcept(e);
88           ASSERT_EQ(s, 0);
89         }
90       }
91     }
92   }
93 
94   for (int e1 : excepts) {
95     for (int e2 : excepts) {
96       for (int e3 : excepts) {
97         for (int e4 : excepts) {
98           for (int e5 : excepts) {
99             int e = e1 | e2 | e3 | e4 | e5;
100             int r = __llvm_libc::feraiseexcept(e);
101             ASSERT_EQ(r, 0);
102             int s = __llvm_libc::fetestexcept(e);
103             ASSERT_EQ(s, e);
104 
105             r = __llvm_libc::feclearexcept(e);
106             ASSERT_EQ(r, 0);
107             s = __llvm_libc::fetestexcept(e);
108             ASSERT_EQ(s, 0);
109           }
110         }
111       }
112     }
113   }
114 
115   int r = __llvm_libc::feraiseexcept(allExcepts);
116   ASSERT_EQ(r, 0);
117   int s = __llvm_libc::fetestexcept(allExcepts);
118   ASSERT_EQ(s, allExcepts);
119 }
120