brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · f3e05d4 Raw
68 lines · cpp
1//===-- Unittests for feholdexcept 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "hdr/types/fenv_t.h"10#include "src/fenv/feholdexcept.h"11 12#include "src/__support/FPUtil/FEnvImpl.h"13#include "src/__support/macros/properties/architectures.h"14#include "test/UnitTest/FEnvSafeTest.h"15#include "test/UnitTest/FPExceptMatcher.h"16#include "test/UnitTest/Test.h"17 18#include "excepts.h"19 20using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;21 22TEST_F(LlvmLibcFEnvTest, RaiseAndCrash) {23#if defined(LIBC_TARGET_ARCH_IS_ANY_ARM) ||                                    \24    defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)25  // Few Arm HW implementations do not trap exceptions. We skip this test26  // completely on such HW.27  //28  // Whether HW supports trapping exceptions or not is deduced by enabling an29  // exception and reading back to see if the exception got enabled. If the30  // exception did not get enabled, then it means that the HW does not support31  // trapping exceptions.32  LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);33  LIBC_NAMESPACE::fputil::enable_except(FE_DIVBYZERO);34  if (LIBC_NAMESPACE::fputil::get_except() == 0)35    return;36#endif // Architectures where exception trapping is not supported37 38  int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,39                   FE_UNDERFLOW};40 41  for (int e : excepts) {42    fenv_t env;43    LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);44    LIBC_NAMESPACE::fputil::enable_except(e);45    ASSERT_EQ(LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT), 0);46    ASSERT_EQ(LIBC_NAMESPACE::feholdexcept(&env), 0);47    // feholdexcept should disable all excepts so raising an exception48    // should not crash/invoke the exception handler.49    ASSERT_EQ(LIBC_NAMESPACE::fputil::raise_except(e), 0);50 51    ASSERT_RAISES_FP_EXCEPT([=] {52      // When we put back the saved env, which has the exception enabled, it53      // should crash with SIGFPE. Note that we set the old environment54      // back inside this closure because in some test frameworks like Fuchsia's55      // zxtest, this test translates to a death test in which this closure is56      // run in a different thread. So, we set the old environment inside57      // this closure so that the exception gets enabled for the thread running58      // this closure.59      LIBC_NAMESPACE::fputil::set_env(&env);60      LIBC_NAMESPACE::fputil::raise_except(e);61    });62 63    // Cleanup64    LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);65    ASSERT_EQ(LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT), 0);66  }67}68