1b7e05c87SSiva Chandra Reddy //===-- Unittests for feholdexcept with exceptions enabled ----------------===//
2b7e05c87SSiva Chandra Reddy //
3b7e05c87SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b7e05c87SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5b7e05c87SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b7e05c87SSiva Chandra Reddy //
7b7e05c87SSiva Chandra Reddy //===----------------------------------------------------------------------===//
8b7e05c87SSiva Chandra Reddy
9b7e05c87SSiva Chandra Reddy #include "src/fenv/feholdexcept.h"
10b7e05c87SSiva Chandra Reddy
11*76ec69a9STue Ly #include "src/__support/FPUtil/FEnvImpl.h"
120aea170bSGuillaume Chatelet #include "src/__support/architectures.h"
136c3f53c7SSiva Chandra Reddy #include "utils/UnitTest/FPExceptMatcher.h"
14b7e05c87SSiva Chandra Reddy #include "utils/UnitTest/Test.h"
15b7e05c87SSiva Chandra Reddy
16b7e05c87SSiva Chandra Reddy #include <fenv.h>
17b7e05c87SSiva Chandra Reddy
TEST(LlvmLibcFEnvTest,RaiseAndCrash)18b7e05c87SSiva Chandra Reddy TEST(LlvmLibcFEnvTest, RaiseAndCrash) {
190aea170bSGuillaume Chatelet #if defined(LLVM_LIBC_ARCH_AARCH64)
20c5cfbe40SSiva Chandra Reddy // Few aarch64 HW implementations do not trap exceptions. We skip this test
21c5cfbe40SSiva Chandra Reddy // completely on such HW.
22c5cfbe40SSiva Chandra Reddy //
23c5cfbe40SSiva Chandra Reddy // Whether HW supports trapping exceptions or not is deduced by enabling an
24c5cfbe40SSiva Chandra Reddy // exception and reading back to see if the exception got enabled. If the
25c5cfbe40SSiva Chandra Reddy // exception did not get enabled, then it means that the HW does not support
26c5cfbe40SSiva Chandra Reddy // trapping exceptions.
271c92911eSMichael Jones __llvm_libc::fputil::disable_except(FE_ALL_EXCEPT);
281c92911eSMichael Jones __llvm_libc::fputil::enable_except(FE_DIVBYZERO);
291c92911eSMichael Jones if (__llvm_libc::fputil::get_except() == 0)
30c5cfbe40SSiva Chandra Reddy return;
310aea170bSGuillaume Chatelet #endif // defined(LLVM_LIBC_ARCH_AARCH64)
32c5cfbe40SSiva Chandra Reddy
33b7e05c87SSiva Chandra Reddy int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
34b7e05c87SSiva Chandra Reddy FE_UNDERFLOW};
35b7e05c87SSiva Chandra Reddy
36b7e05c87SSiva Chandra Reddy for (int e : excepts) {
37b7e05c87SSiva Chandra Reddy fenv_t env;
381c92911eSMichael Jones __llvm_libc::fputil::disable_except(FE_ALL_EXCEPT);
391c92911eSMichael Jones __llvm_libc::fputil::enable_except(e);
401c92911eSMichael Jones ASSERT_EQ(__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT), 0);
41b7e05c87SSiva Chandra Reddy ASSERT_EQ(__llvm_libc::feholdexcept(&env), 0);
42b7e05c87SSiva Chandra Reddy // feholdexcept should disable all excepts so raising an exception
43b7e05c87SSiva Chandra Reddy // should not crash/invoke the exception handler.
441c92911eSMichael Jones ASSERT_EQ(__llvm_libc::fputil::raise_except(e), 0);
45b7e05c87SSiva Chandra Reddy
46c24c18bbSSiva Chandra Reddy ASSERT_RAISES_FP_EXCEPT([=] {
47c24c18bbSSiva Chandra Reddy // When we put back the saved env, which has the exception enabled, it
48c24c18bbSSiva Chandra Reddy // should crash with SIGFPE. Note that we set the old environment
49c24c18bbSSiva Chandra Reddy // back inside this closure because in some test frameworks like Fuchsia's
50c24c18bbSSiva Chandra Reddy // zxtest, this test translates to a death test in which this closure is
51c24c18bbSSiva Chandra Reddy // run in a different thread. So, we set the old environment inside
52c24c18bbSSiva Chandra Reddy // this closure so that the exception gets enabled for the thread running
53c24c18bbSSiva Chandra Reddy // this closure.
541c92911eSMichael Jones __llvm_libc::fputil::set_env(&env);
551c92911eSMichael Jones __llvm_libc::fputil::raise_except(e);
56c24c18bbSSiva Chandra Reddy });
57c24c18bbSSiva Chandra Reddy
58c24c18bbSSiva Chandra Reddy // Cleanup
591c92911eSMichael Jones __llvm_libc::fputil::disable_except(FE_ALL_EXCEPT);
601c92911eSMichael Jones ASSERT_EQ(__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT), 0);
61b7e05c87SSiva Chandra Reddy }
62b7e05c87SSiva Chandra Reddy }
63