78 lines · cpp
1//===-- Unittests for fe{get|set|test}exceptflag --------------------------===//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/fexcept_t.h"10#include "src/fenv/fegetexceptflag.h"11#include "src/fenv/fesetexceptflag.h"12#include "src/fenv/fetestexceptflag.h"13 14#include "src/__support/FPUtil/FEnvImpl.h"15#include "test/UnitTest/FEnvSafeTest.h"16#include "test/UnitTest/Test.h"17 18#include "excepts.h"19 20using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;21 22TEST_F(LlvmLibcFEnvTest, GetSetTestExceptFlag) {23 // We will disable all exceptions to prevent invocation of the exception24 // handler.25 LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);26 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);27 28 for (int e : EXCEPTS) {29 // The overall idea is to raise an except and save the exception flags.30 // Next, clear the flags and then set the saved exception flags. This31 // should set the flag corresponding to the previously raised exception.32 LIBC_NAMESPACE::fputil::raise_except(e);33 // Make sure that the exception flag is set.34 ASSERT_NE(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & e, 0);35 36 fexcept_t eflags;37 ASSERT_EQ(LIBC_NAMESPACE::fegetexceptflag(&eflags, FE_ALL_EXCEPT), 0);38 39 LIBC_NAMESPACE::fputil::clear_except(e);40 ASSERT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & e, 0);41 42 ASSERT_EQ(LIBC_NAMESPACE::fesetexceptflag(&eflags, FE_ALL_EXCEPT), 0);43 ASSERT_NE(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & e, 0);44 45 // Exception flags are exactly the flags corresponding to the previously46 // raised exception.47 ASSERT_EQ(LIBC_NAMESPACE::fetestexceptflag(&eflags, FE_ALL_EXCEPT),48 LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT));49 50 // Cleanup. We clear all excepts as raising excepts like FE_OVERFLOW51 // can also raise FE_INEXACT.52 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);53 }54 55 // Next, we will raise one exception, save the flag and clear all exceptions.56 LIBC_NAMESPACE::fputil::raise_except(FE_INVALID);57 fexcept_t invalid_flag;58 LIBC_NAMESPACE::fegetexceptflag(&invalid_flag, FE_ALL_EXCEPT);59 ASSERT_EQ(LIBC_NAMESPACE::fetestexceptflag(&invalid_flag, FE_ALL_EXCEPT),60 FE_INVALID);61 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);62 63 // Raise two other exceptions and verify that they are set.64 LIBC_NAMESPACE::fputil::raise_except(FE_OVERFLOW | FE_INEXACT);65 fexcept_t overflow_and_inexact_flag;66 LIBC_NAMESPACE::fegetexceptflag(&overflow_and_inexact_flag, FE_ALL_EXCEPT);67 ASSERT_EQ(LIBC_NAMESPACE::fetestexceptflag(&overflow_and_inexact_flag,68 FE_ALL_EXCEPT),69 FE_OVERFLOW | FE_INEXACT);70 ASSERT_EQ(LIBC_NAMESPACE::fetestexceptflag(&overflow_and_inexact_flag,71 FE_OVERFLOW | FE_INEXACT),72 FE_OVERFLOW | FE_INEXACT);73 74 // When we set the flags and test, we should only see FE_INVALID.75 LIBC_NAMESPACE::fesetexceptflag(&invalid_flag, FE_ALL_EXCEPT);76 EXPECT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT), FE_INVALID);77}78