1//===-- Unittests for feenableexcept -------------------------------------===//
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/__support/macros/properties/architectures.h"
10#include "src/fenv/fedisableexcept.h"
11#include "src/fenv/feenableexcept.h"
12#include "src/fenv/fegetexcept.h"
13
14#include "test/UnitTest/FEnvSafeTest.h"
15#include "test/UnitTest/Test.h"
16
17#include "hdr/fenv_macros.h"
18
19#include "excepts.h"
20
21using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
22
23TEST_F(LlvmLibcFEnvTest, EnableTest) {
24#if defined(LIBC_TARGET_ARCH_IS_ANY_ARM) || \
25 defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
26 // Few Arm HW implementations do not trap exceptions. We skip this test
27 // completely on such HW.
28 //
29 // Whether HW supports trapping exceptions or not is deduced by enabling an
30 // exception and reading back to see if the exception got enabled. If the
31 // exception did not get enabled, then it means that the HW does not support
32 // trapping exceptions.
33 LIBC_NAMESPACE::fedisableexcept(FE_ALL_EXCEPT);
34 LIBC_NAMESPACE::feenableexcept(FE_DIVBYZERO);
35 if (LIBC_NAMESPACE::fegetexcept() == 0)
36 return;
37#endif // Architectures where exception trapping is not supported
38
39 int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
40 FE_UNDERFLOW};
41 LIBC_NAMESPACE::fedisableexcept(FE_ALL_EXCEPT);
42 ASSERT_EQ(0, LIBC_NAMESPACE::fegetexcept());
43
44 for (int e : excepts) {
45 LIBC_NAMESPACE::feenableexcept(e);
46 ASSERT_EQ(e, LIBC_NAMESPACE::fegetexcept());
47 LIBC_NAMESPACE::fedisableexcept(e);
48 }
49
50 for (int e1 : excepts) {
51 for (int e2 : excepts) {
52 LIBC_NAMESPACE::feenableexcept(e1 | e2);
53 ASSERT_EQ(e1 | e2, LIBC_NAMESPACE::fegetexcept());
54 LIBC_NAMESPACE::fedisableexcept(e1 | e2);
55 }
56 }
57
58 for (int e1 : excepts) {
59 for (int e2 : excepts) {
60 for (int e3 : excepts) {
61 LIBC_NAMESPACE::feenableexcept(e1 | e2 | e3);
62 ASSERT_EQ(e1 | e2 | e3, LIBC_NAMESPACE::fegetexcept());
63 LIBC_NAMESPACE::fedisableexcept(e1 | e2 | e3);
64 }
65 }
66 }
67
68 for (int e1 : excepts) {
69 for (int e2 : excepts) {
70 for (int e3 : excepts) {
71 for (int e4 : excepts) {
72 LIBC_NAMESPACE::feenableexcept(e1 | e2 | e3 | e4);
73 ASSERT_EQ(e1 | e2 | e3 | e4, LIBC_NAMESPACE::fegetexcept());
74 LIBC_NAMESPACE::fedisableexcept(e1 | e2 | e3 | e4);
75 }
76 }
77 }
78 }
79
80 for (int e1 : excepts) {
81 for (int e2 : excepts) {
82 for (int e3 : excepts) {
83 for (int e4 : excepts) {
84 for (int e5 : excepts) {
85 LIBC_NAMESPACE::feenableexcept(e1 | e2 | e3 | e4 | e5);
86 ASSERT_EQ(e1 | e2 | e3 | e4 | e5, LIBC_NAMESPACE::fegetexcept());
87 LIBC_NAMESPACE::fedisableexcept(e1 | e2 | e3 | e4 | e5);
88 }
89 }
90 }
91 }
92 }
93}
94

source code of libc/test/src/fenv/feenableexcept_test.cpp