
This would ensure that errno value is cleared out before test execution and tests pass even when LIBC_ERRNO_MODE_SYSTEM_INLINE is specified (and errno may be clobbered before test execution). A lot of the tests would fail, however, since errno would end up getting set to EDOM or ERANGE during test execution and never validated before the end of the test. This should be fixed - and errno should be explicitly checked or ignored in all of those cases, but for now add a TODO to address it later (see open issue #135320) and clear out errno in test fixture to avoid test failures.
94 lines
3.3 KiB
C++
94 lines
3.3 KiB
C++
//===-- FEnvSafeTest.cpp ---------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
#include "FEnvSafeTest.h"
|
|
|
|
#include "src/__support/FPUtil/FEnvImpl.h"
|
|
#include "src/__support/libc_errno.h"
|
|
#include "src/__support/macros/config.h"
|
|
#include "src/__support/macros/properties/architectures.h"
|
|
#include "test/UnitTest/ErrnoCheckingTest.h"
|
|
|
|
namespace LIBC_NAMESPACE_DECL {
|
|
namespace testing {
|
|
|
|
void FEnvSafeTest::PreserveFEnv::check() {
|
|
fenv_t after;
|
|
test.get_fenv(after);
|
|
test.expect_fenv_eq(before, after);
|
|
}
|
|
|
|
void FEnvSafeTest::TearDown() {
|
|
if (!should_be_unchanged) {
|
|
restore_fenv();
|
|
}
|
|
// TODO (PR 135320): Remove this override once all FEnvSafeTest instances are
|
|
// updated to validate or ignore errno.
|
|
libc_errno = 0;
|
|
ErrnoCheckingTest::TearDown();
|
|
}
|
|
|
|
void FEnvSafeTest::get_fenv(fenv_t &fenv) {
|
|
ASSERT_EQ(LIBC_NAMESPACE::fputil::get_env(&fenv), 0);
|
|
}
|
|
|
|
void FEnvSafeTest::set_fenv(const fenv_t &fenv) {
|
|
ASSERT_EQ(LIBC_NAMESPACE::fputil::set_env(&fenv), 0);
|
|
}
|
|
|
|
void FEnvSafeTest::expect_fenv_eq(const fenv_t &before_fenv,
|
|
const fenv_t &after_fenv) {
|
|
#if defined(LIBC_TARGET_ARCH_IS_AARCH64)
|
|
using FPState = LIBC_NAMESPACE::fputil::FEnv::FPState;
|
|
const FPState &before_state = reinterpret_cast<const FPState &>(before_fenv);
|
|
const FPState &after_state = reinterpret_cast<const FPState &>(after_fenv);
|
|
|
|
EXPECT_EQ(before_state.ControlWord, after_state.ControlWord);
|
|
EXPECT_EQ(before_state.StatusWord, after_state.StatusWord);
|
|
|
|
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__)
|
|
using LIBC_NAMESPACE::fputil::internal::FPState;
|
|
const FPState &before_state = reinterpret_cast<const FPState &>(before_fenv);
|
|
const FPState &after_state = reinterpret_cast<const FPState &>(after_fenv);
|
|
|
|
#if defined(_WIN32)
|
|
EXPECT_EQ(before_state.control_word, after_state.control_word);
|
|
EXPECT_EQ(before_state.status_word, after_state.status_word);
|
|
#elif defined(__APPLE__)
|
|
EXPECT_EQ(before_state.control_word, after_state.control_word);
|
|
EXPECT_EQ(before_state.status_word, after_state.status_word);
|
|
EXPECT_EQ(before_state.mxcsr, after_state.mxcsr);
|
|
#else
|
|
EXPECT_EQ(before_state.x87_status.control_word,
|
|
after_state.x87_status.control_word);
|
|
EXPECT_EQ(before_state.x87_status.status_word,
|
|
after_state.x87_status.status_word);
|
|
EXPECT_EQ(before_state.mxcsr, after_state.mxcsr);
|
|
#endif
|
|
|
|
#elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP)
|
|
using LIBC_NAMESPACE::fputil::FEnv;
|
|
const FEnv &before_state = reinterpret_cast<const FEnv &>(before_fenv);
|
|
const FEnv &after_state = reinterpret_cast<const FEnv &>(after_fenv);
|
|
|
|
EXPECT_EQ(before_state.fpscr, after_state.fpscr);
|
|
|
|
#elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
|
|
const uint32_t &before_fcsr = reinterpret_cast<const uint32_t &>(before_fenv);
|
|
const uint32_t &after_fcsr = reinterpret_cast<const uint32_t &>(after_fenv);
|
|
EXPECT_EQ(before_fcsr, after_fcsr);
|
|
|
|
#else
|
|
// No arch-specific `fenv_t` support, so nothing to compare.
|
|
|
|
#endif
|
|
}
|
|
|
|
} // namespace testing
|
|
} // namespace LIBC_NAMESPACE_DECL
|