1 //===-- Unittests for fegetenv and fesetenv -------------------------------===// 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/fegetenv.h" 10 #include "src/fenv/fegetround.h" 11 #include "src/fenv/fesetenv.h" 12 #include "src/fenv/fesetround.h" 13 14 #include "src/__support/FPUtil/FEnvImpl.h" 15 #include "utils/UnitTest/Test.h" 16 17 #include <fenv.h> 18 19 TEST(LlvmLibcFenvTest, GetEnvAndSetEnv) { 20 // We will disable all exceptions to prevent invocation of the exception 21 // handler. 22 __llvm_libc::fputil::disable_except(FE_ALL_EXCEPT); 23 24 int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW, 25 FE_UNDERFLOW}; 26 27 for (int e : excepts) { 28 __llvm_libc::fputil::clear_except(FE_ALL_EXCEPT); 29 30 // Save the cleared environment. 31 fenv_t env; 32 ASSERT_EQ(__llvm_libc::fegetenv(&env), 0); 33 34 __llvm_libc::fputil::raise_except(e); 35 // Make sure that the exception is raised. 36 ASSERT_NE(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT) & e, 0); 37 38 ASSERT_EQ(__llvm_libc::fesetenv(&env), 0); 39 ASSERT_EQ(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT) & e, 0); 40 } 41 } 42 43 TEST(LlvmLibcFenvTest, Set_FE_DFL_ENV) { 44 // We will disable all exceptions to prevent invocation of the exception 45 // handler. 46 __llvm_libc::fputil::disable_except(FE_ALL_EXCEPT); 47 48 int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW, 49 FE_UNDERFLOW}; 50 51 for (int e : excepts) { 52 __llvm_libc::fputil::clear_except(FE_ALL_EXCEPT); 53 54 // Save the cleared environment. 55 fenv_t env; 56 ASSERT_EQ(__llvm_libc::fegetenv(&env), 0); 57 58 __llvm_libc::fputil::raise_except(e); 59 // Make sure that the exception is raised. 60 ASSERT_NE(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT) & e, 0); 61 62 ASSERT_EQ(__llvm_libc::fesetenv(FE_DFL_ENV), 0); 63 // Setting the default env should clear all exceptions. 64 ASSERT_EQ(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT) & e, 0); 65 } 66 67 ASSERT_EQ(__llvm_libc::fesetround(FE_DOWNWARD), 0); 68 ASSERT_EQ(__llvm_libc::fesetenv(FE_DFL_ENV), 0); 69 // Setting the default env should set rounding mode to FE_TONEAREST. 70 int rm = __llvm_libc::fegetround(); 71 EXPECT_EQ(rm, FE_TONEAREST); 72 } 73 74 #ifdef _WIN32 75 TEST(LlvmLibcFenvTest, Windows_Set_Get_Test) { 76 // If a valid fenv_t is written, then reading it back out should be identical. 77 fenv_t setEnv = {0x7e00053e, 0x0f00000f}; 78 fenv_t getEnv; 79 ASSERT_EQ(__llvm_libc::fesetenv(&setEnv), 0); 80 ASSERT_EQ(__llvm_libc::fegetenv(&getEnv), 0); 81 82 ASSERT_EQ(setEnv._Fe_ctl, getEnv._Fe_ctl); 83 ASSERT_EQ(setEnv._Fe_stat, getEnv._Fe_stat); 84 } 85 #endif 86