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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/fenv/feholdexcept.h" 10 11 #include "src/__support/FPUtil/FEnvUtils.h" 12 #include "src/__support/FPUtil/FPExceptMatcher.h" 13 #include "utils/UnitTest/Test.h" 14 15 #include <fenv.h> 16 17 TEST(LlvmLibcFEnvTest, RaiseAndCrash) { 18 int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW, 19 FE_UNDERFLOW}; 20 21 for (int e : excepts) { 22 fenv_t env; 23 __llvm_libc::fputil::disableExcept(FE_ALL_EXCEPT); 24 __llvm_libc::fputil::enableExcept(e); 25 ASSERT_EQ(__llvm_libc::fputil::clearExcept(FE_ALL_EXCEPT), 0); 26 ASSERT_EQ(__llvm_libc::feholdexcept(&env), 0); 27 // feholdexcept should disable all excepts so raising an exception 28 // should not crash/invoke the exception handler. 29 ASSERT_EQ(__llvm_libc::fputil::raiseExcept(e), 0); 30 31 ASSERT_RAISES_FP_EXCEPT([=] { 32 // When we put back the saved env, which has the exception enabled, it 33 // should crash with SIGFPE. Note that we set the old environment 34 // back inside this closure because in some test frameworks like Fuchsia's 35 // zxtest, this test translates to a death test in which this closure is 36 // run in a different thread. So, we set the old environment inside 37 // this closure so that the exception gets enabled for the thread running 38 // this closure. 39 __llvm_libc::fputil::setEnv(&env); 40 __llvm_libc::fputil::raiseExcept(e); 41 }); 42 43 // Cleanup 44 __llvm_libc::fputil::disableExcept(FE_ALL_EXCEPT); 45 ASSERT_EQ(__llvm_libc::fputil::clearExcept(FE_ALL_EXCEPT), 0); 46 } 47 } 48