1 //===-- Unittests for feclearexcept with exceptions enabled ---------------===//
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 
11 #include "src/__support/FPUtil/FEnvUtils.h"
12 #include "utils/UnitTest/Test.h"
13 
14 #include <fenv.h>
15 #include <stdint.h>
16 
17 TEST(LlvmLibcFEnvTest, ClearTest) {
18   uint16_t excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
19                         FE_UNDERFLOW};
20   __llvm_libc::fputil::disableExcept(FE_ALL_EXCEPT);
21   __llvm_libc::fputil::clearExcept(FE_ALL_EXCEPT);
22 
23   for (uint16_t e : excepts)
24     ASSERT_EQ(__llvm_libc::fputil::testExcept(e), 0);
25 
26   __llvm_libc::fputil::raiseExcept(FE_ALL_EXCEPT);
27   for (uint16_t e : excepts) {
28     // We clear one exception and test to verify that it was cleared.
29     __llvm_libc::feclearexcept(e);
30     ASSERT_EQ(uint16_t(__llvm_libc::fputil::testExcept(FE_ALL_EXCEPT)),
31               uint16_t(FE_ALL_EXCEPT & ~e));
32     // After clearing, we raise the exception again.
33     __llvm_libc::fputil::raiseExcept(e);
34   }
35 
36   for (uint16_t e1 : excepts) {
37     for (uint16_t e2 : excepts) {
38       __llvm_libc::feclearexcept(e1 | e2);
39       ASSERT_EQ(uint16_t(__llvm_libc::fputil::testExcept(FE_ALL_EXCEPT)),
40                 uint16_t(FE_ALL_EXCEPT & ~(e1 | e2)));
41       __llvm_libc::fputil::raiseExcept(e1 | e2);
42     }
43   }
44 
45   for (uint16_t e1 : excepts) {
46     for (uint16_t e2 : excepts) {
47       for (uint16_t e3 : excepts) {
48         __llvm_libc::feclearexcept(e1 | e2 | e3);
49         ASSERT_EQ(uint16_t(__llvm_libc::fputil::testExcept(FE_ALL_EXCEPT)),
50                   uint16_t(FE_ALL_EXCEPT & ~(e1 | e2 | e3)));
51         __llvm_libc::fputil::raiseExcept(e1 | e2 | e3);
52       }
53     }
54   }
55 
56   for (uint16_t e1 : excepts) {
57     for (uint16_t e2 : excepts) {
58       for (uint16_t e3 : excepts) {
59         for (uint16_t e4 : excepts) {
60           __llvm_libc::feclearexcept(e1 | e2 | e3 | e4);
61           ASSERT_EQ(uint16_t(__llvm_libc::fputil::testExcept(FE_ALL_EXCEPT)),
62                     uint16_t(FE_ALL_EXCEPT & ~(e1 | e2 | e3 | e4)));
63           __llvm_libc::fputil::raiseExcept(e1 | e2 | e3 | e4);
64         }
65       }
66     }
67   }
68 
69   for (uint16_t e1 : excepts) {
70     for (uint16_t e2 : excepts) {
71       for (uint16_t e3 : excepts) {
72         for (uint16_t e4 : excepts) {
73           for (uint16_t e5 : excepts) {
74             __llvm_libc::feclearexcept(e1 | e2 | e3 | e4 | e5);
75             ASSERT_EQ(uint16_t(__llvm_libc::fputil::testExcept(FE_ALL_EXCEPT)),
76                       uint16_t(FE_ALL_EXCEPT & ~(e1 | e2 | e3 | e4 | e5)));
77             __llvm_libc::fputil::raiseExcept(e1 | e2 | e3 | e4 | e5);
78           }
79         }
80       }
81     }
82   }
83 }
84