1 //===-- Unittests for feraiseexcept with exceptions enabled ---------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "src/fenv/feclearexcept.h"
10 #include "src/fenv/feraiseexcept.h"
11 #include "src/fenv/fetestexcept.h"
13 #include "src/__support/FPUtil/FEnvImpl.h"
14 #include "src/__support/macros/properties/architectures.h"
15 #include "test/UnitTest/FEnvSafeTest.h"
16 #include "test/UnitTest/FPExceptMatcher.h"
17 #include "test/UnitTest/Test.h"
19 #include "hdr/fenv_macros.h"
24 using LlvmLibcExceptionStatusTest
= LIBC_NAMESPACE::testing::FEnvSafeTest
;
26 // This test enables an exception and verifies that raising that exception
28 TEST_F(LlvmLibcExceptionStatusTest
, RaiseAndCrash
) {
29 #if defined(LIBC_TARGET_ARCH_IS_ANY_ARM) || \
30 defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
31 // Few Arm HW implementations do not trap exceptions. We skip this test
32 // completely on such HW.
34 // Whether HW supports trapping exceptions or not is deduced by enabling an
35 // exception and reading back to see if the exception got enabled. If the
36 // exception did not get enabled, then it means that the HW does not support
37 // trapping exceptions.
38 LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT
);
39 LIBC_NAMESPACE::fputil::enable_except(FE_DIVBYZERO
);
40 if (LIBC_NAMESPACE::fputil::get_except() == 0)
42 #endif // Architectures where exception trapping is not supported
44 // TODO: Install a floating point exception handler and verify that the
45 // the expected exception was raised. One will have to longjmp back from
46 // that exception handler, so such a testing can be done after we have
47 // longjmp implemented.
49 for (int e
: EXCEPTS
) {
50 LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT
);
51 LIBC_NAMESPACE::fputil::enable_except(e
);
52 ASSERT_EQ(LIBC_NAMESPACE::feclearexcept(FE_ALL_EXCEPT
), 0);
53 // Raising all exceptions except |e| should not call the
54 // SIGFPE handler. They should set the exception flag though,
55 // so we verify that. Since other exceptions like FE_DIVBYZERO
56 // can raise FE_INEXACT as well, we don't verify the other
57 // exception flags when FE_INEXACT is enabled.
58 if (e
!= FE_INEXACT
) {
59 int others
= ALL_EXCEPTS
& ~e
;
60 ASSERT_EQ(LIBC_NAMESPACE::feraiseexcept(others
), 0);
61 ASSERT_EQ(LIBC_NAMESPACE::fetestexcept(others
), others
);
64 ASSERT_RAISES_FP_EXCEPT([=] {
65 // In test frameworks like Fuchsia's zxtest, this translates to
66 // a death test which runs this closure in a different thread. So,
67 // we enable the exception again inside this closure so that the
68 // exception gets enabled for the thread running this closure.
69 LIBC_NAMESPACE::fputil::enable_except(e
);
70 LIBC_NAMESPACE::feraiseexcept(e
);
74 LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT
);
75 ASSERT_EQ(LIBC_NAMESPACE::feclearexcept(FE_ALL_EXCEPT
), 0);