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/FEnv.h"
14 #include "utils/UnitTest/Test.h"
15 
16 #include <fenv.h>
17 
TEST(ExceptionStatusTest,RaiseAndTest)18 TEST(ExceptionStatusTest, 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   for (int e : excepts) {
28     int r = __llvm_libc::feraiseexcept(e);
29     EXPECT_EQ(r, 0);
30     int s = __llvm_libc::fetestexcept(e);
31     EXPECT_EQ(s, e);
32 
33     r = __llvm_libc::feclearexcept(e);
34     EXPECT_EQ(r, 0);
35     s = __llvm_libc::fetestexcept(e);
36     EXPECT_EQ(s, 0);
37   }
38 
39   for (int e1 : excepts) {
40     for (int e2 : excepts) {
41       int e = e1 | e2;
42       int r = __llvm_libc::feraiseexcept(e);
43       EXPECT_EQ(r, 0);
44       int s = __llvm_libc::fetestexcept(e);
45       EXPECT_EQ(s, e);
46 
47       r = __llvm_libc::feclearexcept(e);
48       EXPECT_EQ(r, 0);
49       s = __llvm_libc::fetestexcept(e);
50       EXPECT_EQ(s, 0);
51     }
52   }
53 
54   for (int e1 : excepts) {
55     for (int e2 : excepts) {
56       for (int e3 : excepts) {
57         int e = e1 | e2 | e3;
58         int r = __llvm_libc::feraiseexcept(e);
59         EXPECT_EQ(r, 0);
60         int s = __llvm_libc::fetestexcept(e);
61         EXPECT_EQ(s, e);
62 
63         r = __llvm_libc::feclearexcept(e);
64         EXPECT_EQ(r, 0);
65         s = __llvm_libc::fetestexcept(e);
66         EXPECT_EQ(s, 0);
67       }
68     }
69   }
70 
71   for (int e1 : excepts) {
72     for (int e2 : excepts) {
73       for (int e3 : excepts) {
74         for (int e4 : excepts) {
75           int e = e1 | e2 | e3 | e4;
76           int r = __llvm_libc::feraiseexcept(e);
77           EXPECT_EQ(r, 0);
78           int s = __llvm_libc::fetestexcept(e);
79           EXPECT_EQ(s, e);
80 
81           r = __llvm_libc::feclearexcept(e);
82           EXPECT_EQ(r, 0);
83           s = __llvm_libc::fetestexcept(e);
84           EXPECT_EQ(s, 0);
85         }
86       }
87     }
88   }
89 
90   for (int e1 : excepts) {
91     for (int e2 : excepts) {
92       for (int e3 : excepts) {
93         for (int e4 : excepts) {
94           for (int e5 : excepts) {
95             int e = e1 | e2 | e3 | e4 | e5;
96             int r = __llvm_libc::feraiseexcept(e);
97             EXPECT_EQ(r, 0);
98             int s = __llvm_libc::fetestexcept(e);
99             EXPECT_EQ(s, e);
100 
101             r = __llvm_libc::feclearexcept(e);
102             EXPECT_EQ(r, 0);
103             s = __llvm_libc::fetestexcept(e);
104             EXPECT_EQ(s, 0);
105           }
106         }
107       }
108     }
109   }
110 
111   int r = __llvm_libc::feraiseexcept(FE_ALL_EXCEPT);
112   EXPECT_EQ(r, 0);
113   int s = __llvm_libc::fetestexcept(FE_ALL_EXCEPT);
114   EXPECT_EQ(s, FE_ALL_EXCEPT);
115 }
116