brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 7d26eab Raw
78 lines · cpp
1//===-- Unittests for feraiseexcept 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 "src/fenv/feclearexcept.h"10#include "src/fenv/feraiseexcept.h"11#include "src/fenv/fetestexcept.h"12 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"18 19#include "hdr/fenv_macros.h"20#include <signal.h>21 22#include "excepts.h"23 24using LlvmLibcExceptionStatusTest = LIBC_NAMESPACE::testing::FEnvSafeTest;25 26// This test enables an exception and verifies that raising that exception27// triggers SIGFPE.28TEST_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 test32  // completely on such HW.33  //34  // Whether HW supports trapping exceptions or not is deduced by enabling an35  // exception and reading back to see if the exception got enabled. If the36  // exception did not get enabled, then it means that the HW does not support37  // 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)41    return;42#endif // Architectures where exception trapping is not supported43 44  // TODO: Install a floating point exception handler and verify that the45  // the expected exception was raised. One will have to longjmp back from46  // that exception handler, so such a testing can be done after we have47  // longjmp implemented.48 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 the54    // SIGFPE handler. They should set the exception flag though,55    // so we verify that. Since other exceptions like FE_DIVBYZERO56    // can raise FE_INEXACT as well, we don't verify the other57    // 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);62    }63 64    ASSERT_RAISES_FP_EXCEPT([=] {65      // In test frameworks like Fuchsia's zxtest, this translates to66      // a death test which runs this closure in a different thread. So,67      // we enable the exception again inside this closure so that the68      // exception gets enabled for the thread running this closure.69      LIBC_NAMESPACE::fputil::enable_except(e);70      LIBC_NAMESPACE::feraiseexcept(e);71    });72 73    // Cleanup.74    LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);75    ASSERT_EQ(LIBC_NAMESPACE::feclearexcept(FE_ALL_EXCEPT), 0);76  }77}78