summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLLVM libc <llvm-libc@google.com>2024-04-25 01:31:16 +0530
committerCopybara-Service <copybara-worker@google.com>2024-04-26 22:37:29 -0700
commit19d708d96c36a819a02f17dcadc571460b3c5847 (patch)
tree55a0792d8d0b1ed955c2d76b89842cb86a90cadb
parent75a947884d47ca92cea2a2ec06c04d931b5319e8 (diff)
downloadllvm-libc-19d708d96c36a819a02f17dcadc571460b3c5847.tar.gz
Project import generated by Copybara.
GitOrigin-RevId: 11bd19a7a25b291af61b6c06cb249b567c116d0e Change-Id: If0dc40a15e3ef81377af35b688898e836082d027
-rw-r--r--include/llvm-libc-macros/assert-macros.h14
-rw-r--r--include/llvm-libc-types/pthread_rwlockattr_t.h15
-rw-r--r--src/__support/OSUtil/fuchsia/io.h13
-rw-r--r--src/pthread/pthread_rwlockattr_destroy.cpp24
-rw-r--r--src/pthread/pthread_rwlockattr_destroy.h20
-rw-r--r--src/pthread/pthread_rwlockattr_getpshared.cpp23
-rw-r--r--src/pthread/pthread_rwlockattr_getpshared.h21
-rw-r--r--src/pthread/pthread_rwlockattr_init.cpp23
-rw-r--r--src/pthread/pthread_rwlockattr_init.h20
-rw-r--r--src/pthread/pthread_rwlockattr_setpshared.cpp27
-rw-r--r--src/pthread/pthread_rwlockattr_setpshared.h20
-rw-r--r--src/stdlib/bsearch.h2
-rw-r--r--src/sys/stat/linux/chmod.cpp7
-rw-r--r--test/UnitTest/FEnvSafeTest.cpp84
-rw-r--r--test/UnitTest/FEnvSafeTest.h101
-rw-r--r--test/UnitTest/FPExceptMatcher.cpp6
-rw-r--r--test/UnitTest/FPExceptMatcher.h14
-rw-r--r--test/UnitTest/GTest.h23
-rw-r--r--test/UnitTest/LibcTest.h12
-rw-r--r--test/UnitTest/MemoryMatcher.cpp4
-rw-r--r--test/UnitTest/MemoryMatcher.h6
-rw-r--r--test/UnitTest/PigweedTest.h18
-rw-r--r--test/UnitTest/Test.h31
-rw-r--r--test/UnitTest/ZxTest.h (renamed from test/UnitTest/FuchsiaTest.h)17
-rw-r--r--test/include/assert_test.cpp15
-rw-r--r--test/src/fenv/enabled_exceptions_test.cpp18
-rw-r--r--test/src/fenv/exception_flags_test.cpp12
-rw-r--r--test/src/fenv/exception_status_test.cpp43
-rw-r--r--test/src/fenv/excepts.h24
-rw-r--r--test/src/fenv/feclearexcept_test.cpp21
-rw-r--r--test/src/fenv/feenableexcept_test.cpp7
-rw-r--r--test/src/fenv/feholdexcept_test.cpp7
-rw-r--r--test/src/fenv/feupdateenv_test.cpp5
-rw-r--r--test/src/fenv/getenv_and_setenv_test.cpp14
-rw-r--r--test/src/fenv/rounding_mode_test.cpp9
-rw-r--r--test/src/math/CeilTest.h4
-rw-r--r--test/src/math/CopySignTest.h3
-rw-r--r--test/src/math/FAbsTest.h4
-rw-r--r--test/src/math/FDimTest.h3
-rw-r--r--test/src/math/FMaxTest.h4
-rw-r--r--test/src/math/FMinTest.h4
-rw-r--r--test/src/math/FModTest.h4
-rw-r--r--test/src/math/FloorTest.h4
-rw-r--r--test/src/math/FmaTest.h3
-rw-r--r--test/src/math/FrexpTest.h4
-rw-r--r--test/src/math/HypotTest.h3
-rw-r--r--test/src/math/ILogbTest.h3
-rw-r--r--test/src/math/LdExpTest.h3
-rw-r--r--test/src/math/LogbTest.h4
-rw-r--r--test/src/math/ModfTest.h4
-rw-r--r--test/src/math/NextAfterTest.h3
-rw-r--r--test/src/math/RIntTest.h3
-rw-r--r--test/src/math/RemQuoTest.h3
-rw-r--r--test/src/math/RoundEvenTest.h3
-rw-r--r--test/src/math/RoundTest.h4
-rw-r--r--test/src/math/RoundToIntegerTest.h6
-rw-r--r--test/src/math/SqrtTest.h4
-rw-r--r--test/src/math/TruncTest.h4
-rw-r--r--test/src/math/exhaustive/fmod_generic_impl_test.cpp3
-rw-r--r--test/src/math/smoke/CanonicalizeTest.h3
-rw-r--r--test/src/math/smoke/CeilTest.h4
-rw-r--r--test/src/math/smoke/CopySignTest.h3
-rw-r--r--test/src/math/smoke/FAbsTest.h4
-rw-r--r--test/src/math/smoke/FDimTest.h3
-rw-r--r--test/src/math/smoke/FMaxTest.h4
-rw-r--r--test/src/math/smoke/FMaximumMagNumTest.h3
-rw-r--r--test/src/math/smoke/FMaximumMagTest.h3
-rw-r--r--test/src/math/smoke/FMaximumNumTest.h3
-rw-r--r--test/src/math/smoke/FMaximumTest.h3
-rw-r--r--test/src/math/smoke/FMinTest.h4
-rw-r--r--test/src/math/smoke/FMinimumMagNumTest.h3
-rw-r--r--test/src/math/smoke/FMinimumMagTest.h3
-rw-r--r--test/src/math/smoke/FMinimumNumTest.h3
-rw-r--r--test/src/math/smoke/FMinimumTest.h3
-rw-r--r--test/src/math/smoke/FModTest.h4
-rw-r--r--test/src/math/smoke/FloorTest.h4
-rw-r--r--test/src/math/smoke/FmaTest.h3
-rw-r--r--test/src/math/smoke/FrexpTest.h4
-rw-r--r--test/src/math/smoke/FromfpTest.h3
-rw-r--r--test/src/math/smoke/FromfpxTest.h3
-rw-r--r--test/src/math/smoke/HypotTest.h3
-rw-r--r--test/src/math/smoke/ILogbTest.h3
-rw-r--r--test/src/math/smoke/LdExpTest.h3
-rw-r--r--test/src/math/smoke/LogbTest.h4
-rw-r--r--test/src/math/smoke/ModfTest.h4
-rw-r--r--test/src/math/smoke/NextAfterTest.h3
-rw-r--r--test/src/math/smoke/NextDownTest.h3
-rw-r--r--test/src/math/smoke/NextTowardTest.h3
-rw-r--r--test/src/math/smoke/NextUpTest.h3
-rw-r--r--test/src/math/smoke/RIntTest.h3
-rw-r--r--test/src/math/smoke/RemQuoTest.h3
-rw-r--r--test/src/math/smoke/RoundEvenTest.h3
-rw-r--r--test/src/math/smoke/RoundTest.h4
-rw-r--r--test/src/math/smoke/RoundToIntegerTest.h6
-rw-r--r--test/src/math/smoke/SqrtTest.h4
-rw-r--r--test/src/math/smoke/TruncTest.h4
-rw-r--r--test/src/math/smoke/UfromfpTest.h3
-rw-r--r--test/src/math/smoke/UfromfpxTest.h3
-rw-r--r--test/src/math/smoke/nan_test.cpp3
-rw-r--r--test/src/math/smoke/nanf128_test.cpp3
-rw-r--r--test/src/math/smoke/nanf_test.cpp3
-rw-r--r--test/src/math/smoke/nanl_test.cpp3
-rw-r--r--test/src/pthread/pthread_rwlockattr_test.cpp64
103 files changed, 835 insertions, 180 deletions
diff --git a/include/llvm-libc-macros/assert-macros.h b/include/llvm-libc-macros/assert-macros.h
new file mode 100644
index 000000000000..44e14543d856
--- /dev/null
+++ b/include/llvm-libc-macros/assert-macros.h
@@ -0,0 +1,14 @@
+//===-- Definition of macros to be used with assert functions -------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_MACROS_ASSERT_MACROS_H
+#define __LLVM_LIBC_MACROS_ASSERT_MACROS_H
+
+#define __STDC_VERSION_ASSERT_H__ 202311L
+
+#endif // __LLVM_LIBC_MACROS_ASSERT_MACROS_H
diff --git a/include/llvm-libc-types/pthread_rwlockattr_t.h b/include/llvm-libc-types/pthread_rwlockattr_t.h
new file mode 100644
index 000000000000..a63de4f7b438
--- /dev/null
+++ b/include/llvm-libc-types/pthread_rwlockattr_t.h
@@ -0,0 +1,15 @@
+//===-- Definition of pthread_rwlockattr_t type ---------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H
+#define LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H
+
+typedef struct {
+ int pshared;
+} pthread_rwlockattr_t;
+
+#endif // LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H
diff --git a/src/__support/OSUtil/fuchsia/io.h b/src/__support/OSUtil/fuchsia/io.h
index 9a5e00beaa31..f68d734492fa 100644
--- a/src/__support/OSUtil/fuchsia/io.h
+++ b/src/__support/OSUtil/fuchsia/io.h
@@ -9,18 +9,23 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_FUCHSIA_IO_H
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_FUCHSIA_IO_H
-#ifndef LIBC_COPT_TEST_USE_FUCHSIA
-#error this file should only be used by tests
-#endif
-
#include "src/__support/CPP/string_view.h"
+#include <iostream>
#include <zircon/sanitizer.h>
namespace LIBC_NAMESPACE {
LIBC_INLINE void write_to_stderr(cpp::string_view msg) {
+#if defined(LIBC_COPT_TEST_USE_ZXTEST)
+ // This is used in standalone context where there is nothing like POSIX I/O.
__sanitizer_log_write(msg.data(), msg.size());
+#elif defined(LIBC_COPT_TEST_USE_GTEST)
+ // The gtest framework already relies on full standard C++ I/O via fdio.
+ std::cerr << std::string_view{msg.data(), msg.size()};
+#else
+#error this file should only be used by tests
+#endif
}
} // namespace LIBC_NAMESPACE
diff --git a/src/pthread/pthread_rwlockattr_destroy.cpp b/src/pthread/pthread_rwlockattr_destroy.cpp
new file mode 100644
index 000000000000..e3ca75112f0e
--- /dev/null
+++ b/src/pthread/pthread_rwlockattr_destroy.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of the pthread_rwlockattr_destroy ------------------===//
+//
+// 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 "pthread_rwlockattr_destroy.h"
+
+#include "src/__support/common.h"
+
+#include <pthread.h> // pthread_rwlockattr_t
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_destroy,
+ (pthread_rwlockattr_t * attr [[gnu::unused]])) {
+ // Initializing a pthread_rwlockattr_t acquires no resources, so this is a
+ // no-op.
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/pthread/pthread_rwlockattr_destroy.h b/src/pthread/pthread_rwlockattr_destroy.h
new file mode 100644
index 000000000000..5904d6b00418
--- /dev/null
+++ b/src/pthread/pthread_rwlockattr_destroy.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_rwlockattr_destroy ----*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H
+
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE {
+
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H
diff --git a/src/pthread/pthread_rwlockattr_getpshared.cpp b/src/pthread/pthread_rwlockattr_getpshared.cpp
new file mode 100644
index 000000000000..0dad230a2bde
--- /dev/null
+++ b/src/pthread/pthread_rwlockattr_getpshared.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of the pthread_rwlockattr_getpshared ---------------===//
+//
+// 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 "pthread_rwlockattr_getpshared.h"
+
+#include "src/__support/common.h"
+
+#include <pthread.h> // pthread_rwlockattr_t
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_getpshared,
+ (const pthread_rwlockattr_t *attr, int *pshared)) {
+ *pshared = attr->pshared;
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/pthread/pthread_rwlockattr_getpshared.h b/src/pthread/pthread_rwlockattr_getpshared.h
new file mode 100644
index 000000000000..64843e59aae6
--- /dev/null
+++ b/src/pthread/pthread_rwlockattr_getpshared.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for pthread_rwlockattr_getpshared -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H
+
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE {
+
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr,
+ int *pshared);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H
diff --git a/src/pthread/pthread_rwlockattr_init.cpp b/src/pthread/pthread_rwlockattr_init.cpp
new file mode 100644
index 000000000000..7971f1714db4
--- /dev/null
+++ b/src/pthread/pthread_rwlockattr_init.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of the pthread_rwlockattr_init ---------------------===//
+//
+// 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 "pthread_rwlockattr_init.h"
+
+#include "src/__support/common.h"
+
+#include <pthread.h> // pthread_rwlockattr_t, PTHREAD_PROCESS_PRIVATE
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_init,
+ (pthread_rwlockattr_t * attr)) {
+ attr->pshared = PTHREAD_PROCESS_PRIVATE;
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/pthread/pthread_rwlockattr_init.h b/src/pthread/pthread_rwlockattr_init.h
new file mode 100644
index 000000000000..30ae499fb65d
--- /dev/null
+++ b/src/pthread/pthread_rwlockattr_init.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_rwlockattr_init ----*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H
+
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE {
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H
diff --git a/src/pthread/pthread_rwlockattr_setpshared.cpp b/src/pthread/pthread_rwlockattr_setpshared.cpp
new file mode 100644
index 000000000000..6bcba7c1b493
--- /dev/null
+++ b/src/pthread/pthread_rwlockattr_setpshared.cpp
@@ -0,0 +1,27 @@
+//===-- Implementation of the pthread_rwlockattr_setpshared ---------------===//
+//
+// 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 "pthread_rwlockattr_setpshared.h"
+
+#include "src/__support/common.h"
+
+#include <errno.h> // EINVAL
+#include <pthread.h> // pthread_rwlockattr_t, PTHREAD_PROCESS_SHARED, PTHREAD_PROCESS_PRIVATE
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_setpshared,
+ (pthread_rwlockattr_t * attr, int pshared)) {
+ if (pshared != PTHREAD_PROCESS_SHARED && pshared != PTHREAD_PROCESS_PRIVATE)
+ return EINVAL;
+
+ attr->pshared = pshared;
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/pthread/pthread_rwlockattr_setpshared.h b/src/pthread/pthread_rwlockattr_setpshared.h
new file mode 100644
index 000000000000..393c07d1eecb
--- /dev/null
+++ b/src/pthread/pthread_rwlockattr_setpshared.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_rwlockattr_setpshared -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H
+
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE {
+
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H
diff --git a/src/stdlib/bsearch.h b/src/stdlib/bsearch.h
index 1de7e051ff6c..3590198ba557 100644
--- a/src/stdlib/bsearch.h
+++ b/src/stdlib/bsearch.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_STDLIB_BSEARCH_H
#define LLVM_LIBC_SRC_STDLIB_BSEARCH_H
-#include <stdlib.h>
+#include <stddef.h> // size_t
namespace LIBC_NAMESPACE {
diff --git a/src/sys/stat/linux/chmod.cpp b/src/sys/stat/linux/chmod.cpp
index 085b91691d89..25e5e69af71a 100644
--- a/src/sys/stat/linux/chmod.cpp
+++ b/src/sys/stat/linux/chmod.cpp
@@ -21,11 +21,14 @@ namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(int, chmod, (const char *path, mode_t mode)) {
#ifdef SYS_chmod
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_chmod, path, mode);
+#elif defined(SYS_fchmodat2)
+ int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat2, AT_FDCWD, path,
+ mode, 0, AT_SYMLINK_NOFOLLOW);
#elif defined(SYS_fchmodat)
int ret =
- LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat, AT_FDCWD, path, mode);
+ LIBC_NAMESPACE::syscall_impl<int>(SYS_fchmodat, AT_FDCWD, path, mode, 0);
#else
-#error "chmod and fchmodat syscalls not available."
+#error "chmod, fchmodat and fchmodat2 syscalls not available."
#endif
if (ret < 0) {
diff --git a/test/UnitTest/FEnvSafeTest.cpp b/test/UnitTest/FEnvSafeTest.cpp
new file mode 100644
index 000000000000..905aa9289373
--- /dev/null
+++ b/test/UnitTest/FEnvSafeTest.cpp
@@ -0,0 +1,84 @@
+//===-- 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/macros/properties/architectures.h"
+
+namespace LIBC_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();
+ }
+}
+
+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 LIBC_NAMESPACE::testing
diff --git a/test/UnitTest/FEnvSafeTest.h b/test/UnitTest/FEnvSafeTest.h
new file mode 100644
index 000000000000..d5a8bb7ee667
--- /dev/null
+++ b/test/UnitTest/FEnvSafeTest.h
@@ -0,0 +1,101 @@
+//===-- FEnvSafeTest.h -----------------------------------------*- 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
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_UNITTEST_FPENVSAFE_H
+#define LLVM_LIBC_TEST_UNITTEST_FPENVSAFE_H
+
+#include "hdr/types/fenv_t.h"
+#include "src/__support/CPP/utility.h"
+#include "test/UnitTest/Test.h"
+
+namespace LIBC_NAMESPACE::testing {
+
+// This provides a test fixture (or base class for other test fixtures) that
+// asserts that each test does not leave the FPU state represented by `fenv_t`
+// (aka `FPState`) perturbed from its initial state.
+class FEnvSafeTest : public Test {
+public:
+ void TearDown() override;
+
+protected:
+ // This is an RAII type where `PreserveFEnv preserve{this};` will sample the
+ // `fenv_t` state and restore it when `preserve` goes out of scope.
+ class PreserveFEnv {
+ fenv_t before;
+ FEnvSafeTest &test;
+
+ public:
+ explicit PreserveFEnv(FEnvSafeTest *self) : test{*self} {
+ test.get_fenv(before);
+ }
+
+ // Cause test expectation failures if the current state doesn't match what
+ // was captured in the constructor.
+ void check();
+
+ // Restore the state captured in the constructor.
+ void restore() { test.set_fenv(before); }
+
+ ~PreserveFEnv() { restore(); }
+ };
+
+ // This is an RAII type where `CheckFEnv check{this};` will sample the
+ // `fenv_t` state and require it be the same when `check` goes out of scope.
+ struct CheckFEnv : public PreserveFEnv {
+ using PreserveFEnv::PreserveFEnv;
+
+ ~CheckFEnv() { check(); }
+ };
+
+ // This calls callable() and returns its value, but has EXPECT_* failures if
+ // the `fenv_t` state is not preserved by the call.
+ template <typename T> decltype(auto) check_fenv_preserved(T &&callable) {
+ CheckFEnv check{this};
+ return cpp::forward<T>(callable)();
+ }
+
+ // This calls callable() and returns its value, but saves and restores the
+ // `fenv_t` state around the call.
+ template <typename T>
+ auto with_fenv_preserved(T &&callable)
+ -> decltype(cpp::forward<decltype(callable)>(callable)()) {
+ PreserveFEnv preserve{this};
+ return cpp::forward<T>(callable)();
+ }
+
+ // A test can call these to indicate it will or won't change `fenv_t` state.
+ void will_change_fenv() { should_be_unchanged = false; }
+ void will_not_change_fenv() { should_be_unchanged = true; }
+
+ // This explicitly resets back to the "before" state captured in SetUp().
+ // TearDown() always does this, but should_be_unchanged controls whether
+ // it also causes test failures if a test fails to restore it.
+ void restore_fenv() { check.restore(); }
+
+private:
+ void get_fenv(fenv_t &fenv);
+ void set_fenv(const fenv_t &fenv);
+ void expect_fenv_eq(const fenv_t &before_fenv, const fenv_t &after_fenv);
+
+ CheckFEnv check{this};
+
+ // TODO: Many tests fail if this is true. It needs to be figured out whether
+ // the state should be preserved by each library function under test, and
+ // separately whether each test itself should preserve the state. It
+ // probably isn't important that tests be explicitly written to preserve the
+ // state, as the fixture can (and does) reset it--the next test can rely on
+ // getting "normal" ambient state initially. For library functions that
+ // should preserve the state, that should be checked after each call, not
+ // just after the whole test. So they can use check_fenv_preserved or
+ // with_fenv_preserved as appropriate.
+ bool should_be_unchanged = false;
+};
+
+} // namespace LIBC_NAMESPACE::testing
+
+#endif // LLVM_LIBC_TEST_UNITTEST_FPENVSAFE_H
diff --git a/test/UnitTest/FPExceptMatcher.cpp b/test/UnitTest/FPExceptMatcher.cpp
index 53ea72ad9ddd..c1dfc5392466 100644
--- a/test/UnitTest/FPExceptMatcher.cpp
+++ b/test/UnitTest/FPExceptMatcher.cpp
@@ -8,12 +8,16 @@
#include "FPExceptMatcher.h"
+#include "test/UnitTest/Test.h"
+
#include "hdr/types/fenv_t.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include <memory>
#include <setjmp.h>
#include <signal.h>
+#if LIBC_TEST_HAS_MATCHERS()
+
namespace LIBC_NAMESPACE {
namespace testing {
@@ -49,3 +53,5 @@ FPExceptMatcher::FPExceptMatcher(FunctionCaller *func) {
} // namespace testing
} // namespace LIBC_NAMESPACE
+
+#endif // LIBC_TEST_HAS_MATCHERS()
diff --git a/test/UnitTest/FPExceptMatcher.h b/test/UnitTest/FPExceptMatcher.h
index d36e98d22d4b..5136e381081e 100644
--- a/test/UnitTest/FPExceptMatcher.h
+++ b/test/UnitTest/FPExceptMatcher.h
@@ -9,9 +9,10 @@
#ifndef LLVM_LIBC_TEST_UNITTEST_FPEXCEPTMATCHER_H
#define LLVM_LIBC_TEST_UNITTEST_FPEXCEPTMATCHER_H
-#ifndef LIBC_COPT_TEST_USE_FUCHSIA
-
#include "test/UnitTest/Test.h"
+#include "test/UnitTest/TestLogger.h"
+
+#if LIBC_TEST_HAS_MATCHERS()
namespace LIBC_NAMESPACE {
namespace testing {
@@ -24,7 +25,7 @@ class FPExceptMatcher : public Matcher<bool> {
public:
class FunctionCaller {
public:
- virtual ~FunctionCaller(){};
+ virtual ~FunctionCaller() {}
virtual void call() = 0;
};
@@ -57,8 +58,11 @@ public:
true, \
LIBC_NAMESPACE::testing::FPExceptMatcher( \
LIBC_NAMESPACE::testing::FPExceptMatcher::getFunctionCaller(func)))
-#else
+
+#else // !LIBC_TEST_HAS_MATCHERS()
+
#define ASSERT_RAISES_FP_EXCEPT(func) ASSERT_DEATH(func, WITH_SIGNAL(SIGFPE))
-#endif // LIBC_COPT_TEST_USE_FUCHSIA
+
+#endif // LIBC_TEST_HAS_MATCHERS()
#endif // LLVM_LIBC_TEST_UNITTEST_FPEXCEPTMATCHER_H
diff --git a/test/UnitTest/GTest.h b/test/UnitTest/GTest.h
new file mode 100644
index 000000000000..d1637d3ba658
--- /dev/null
+++ b/test/UnitTest/GTest.h
@@ -0,0 +1,23 @@
+//===-- Header for using the gtest framework -------------------*- 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
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_UTILS_UNITTEST_GTEST_H
+#define LLVM_LIBC_UTILS_UNITTEST_GTEST_H
+
+#include <gtest/gtest.h>
+
+namespace LIBC_NAMESPACE::testing {
+
+using ::testing::Matcher;
+using ::testing::Test;
+
+} // namespace LIBC_NAMESPACE::testing
+
+#define LIBC_TEST_HAS_MATCHERS() (1)
+
+#endif // LLVM_LIBC_UTILS_UNITTEST_GTEST_H
diff --git a/test/UnitTest/LibcTest.h b/test/UnitTest/LibcTest.h
index a813a59d2d67..bba3c6d743be 100644
--- a/test/UnitTest/LibcTest.h
+++ b/test/UnitTest/LibcTest.h
@@ -447,16 +447,6 @@ CString libc_make_test_file_path_func(const char *file_name);
#define ASSERT_STRNE(LHS, RHS) LIBC_TEST_STR_(testStrNe, LHS, RHS, return)
////////////////////////////////////////////////////////////////////////////////
-// Errno checks.
-
-#define ASSERT_ERRNO_EQ(VAL) \
- ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
-#define ASSERT_ERRNO_SUCCESS() \
- ASSERT_EQ(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
-#define ASSERT_ERRNO_FAILURE() \
- ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
-
-////////////////////////////////////////////////////////////////////////////////
// Subprocess checks.
#ifdef ENABLE_SUBPROCESS_TESTS
@@ -494,4 +484,6 @@ CString libc_make_test_file_path_func(const char *file_name);
#define WITH_SIGNAL(X) X
+#define LIBC_TEST_HAS_MATCHERS() (1)
+
#endif // LLVM_LIBC_TEST_UNITTEST_LIBCTEST_H
diff --git a/test/UnitTest/MemoryMatcher.cpp b/test/UnitTest/MemoryMatcher.cpp
index d9d89504dbeb..c18bc4a8ab59 100644
--- a/test/UnitTest/MemoryMatcher.cpp
+++ b/test/UnitTest/MemoryMatcher.cpp
@@ -10,6 +10,8 @@
#include "test/UnitTest/Test.h"
+#if LIBC_TEST_HAS_MATCHERS()
+
using LIBC_NAMESPACE::testing::tlog;
namespace LIBC_NAMESPACE {
@@ -76,3 +78,5 @@ void MemoryMatcher::explainError() {
} // namespace testing
} // namespace LIBC_NAMESPACE
+
+#endif // LIBC_TEST_HAS_MATCHERS()
diff --git a/test/UnitTest/MemoryMatcher.h b/test/UnitTest/MemoryMatcher.h
index c548bafb7ae4..ab77eff153b4 100644
--- a/test/UnitTest/MemoryMatcher.h
+++ b/test/UnitTest/MemoryMatcher.h
@@ -21,7 +21,7 @@ using MemoryView = LIBC_NAMESPACE::cpp::span<const char>;
} // namespace testing
} // namespace LIBC_NAMESPACE
-#ifdef LIBC_COPT_TEST_USE_FUCHSIA
+#if !LIBC_TEST_HAS_MATCHERS()
#define EXPECT_MEM_EQ(expected, actual) \
do { \
@@ -39,7 +39,7 @@ using MemoryView = LIBC_NAMESPACE::cpp::span<const char>;
ASSERT_BYTES_EQ(e.data(), a.data(), e.size()); \
} while (0)
-#else
+#else // LIBC_TEST_HAS_MATCHERS()
namespace LIBC_NAMESPACE::testing {
@@ -64,6 +64,6 @@ public:
#define ASSERT_MEM_EQ(expected, actual) \
ASSERT_THAT(actual, LIBC_NAMESPACE::testing::MemoryMatcher(expected))
-#endif
+#endif // !LIBC_TEST_HAS_MATCHERS()
#endif // LLVM_LIBC_TEST_UNITTEST_MEMORYMATCHER_H
diff --git a/test/UnitTest/PigweedTest.h b/test/UnitTest/PigweedTest.h
deleted file mode 100644
index 855633527fb3..000000000000
--- a/test/UnitTest/PigweedTest.h
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Header for setting up the Pigweed tests -----------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_UTILS_UNITTEST_PIGWEEDTEST_H
-#define LLVM_LIBC_UTILS_UNITTEST_PIGWEEDTEST_H
-
-#include <gtest/gtest.h>
-
-namespace LIBC_NAMESPACE::testing {
-using Test = ::testing::Test;
-}
-
-#endif // LLVM_LIBC_UTILS_UNITTEST_PIGWEEDTEST_H
diff --git a/test/UnitTest/Test.h b/test/UnitTest/Test.h
index f7ce3cfa5cf6..c7729606000c 100644
--- a/test/UnitTest/Test.h
+++ b/test/UnitTest/Test.h
@@ -16,12 +16,35 @@
// redefine it as necessary.
#define libc_make_test_file_path(file_name) (file_name)
-#if defined(LIBC_COPT_TEST_USE_FUCHSIA)
-#include "FuchsiaTest.h"
-#elif defined(LIBC_COPT_TEST_USE_PIGWEED)
-#include "PigweedTest.h"
+// The LIBC_COPT_TEST_USE_* macros can select either of two alternate test
+// frameworks:
+// * gtest, the well-known model for them all
+// * zxtest, the gtest workalike subset sometimes used in the Fuchsia build
+// The default is to use llvm-libc's own gtest workalike framework.
+//
+// All the frameworks provide the basic EXPECT_* and ASSERT_* macros that gtest
+// does. The wrapper headers below define LIBC_NAMESPACE::testing::Test as the
+// base class for test fixture classes. Each also provides a definition of the
+// macro LIBC_TEST_HAS_MATCHERS() for use in `#if` conditionals to guard use of
+// gmock-style matchers, which zxtest does not support.
+
+#if defined(LIBC_COPT_TEST_USE_ZXTEST)
+#include "ZxTest.h"
+// TODO: Migrate Pigweed to setting LIBC_COPT_TEST_USE_GTEST instead.
+#elif defined(LIBC_COPT_TEST_USE_GTEST) || defined(LIBC_COPT_TEST_USE_PIGWEED)
+#include "GTest.h"
#else
#include "LibcTest.h"
#endif
+// These are defined the same way for each framework, in terms of the macros
+// they all provide.
+
+#define ASSERT_ERRNO_EQ(VAL) \
+ ASSERT_EQ(VAL, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+#define ASSERT_ERRNO_SUCCESS() \
+ ASSERT_EQ(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+#define ASSERT_ERRNO_FAILURE() \
+ ASSERT_NE(0, static_cast<int>(LIBC_NAMESPACE::libc_errno))
+
#endif // LLVM_LIBC_TEST_UNITTEST_TEST_H
diff --git a/test/UnitTest/FuchsiaTest.h b/test/UnitTest/ZxTest.h
index e9e8348ee5dd..e6bd1e8b6437 100644
--- a/test/UnitTest/FuchsiaTest.h
+++ b/test/UnitTest/ZxTest.h
@@ -1,13 +1,13 @@
-//===-- Header for setting up the Fuchsia tests -----------------*- C++ -*-===//
+//===-- Header for using Fuchsia's zxtest framework ------------*- 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
//
-//===----------------------------------------------------------------------===//
+//===---------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_UTILS_UNITTEST_FUCHSIATEST_H
-#define LLVM_LIBC_UTILS_UNITTEST_FUCHSIATEST_H
+#ifndef LLVM_LIBC_UTILS_UNITTEST_ZXTEST_H
+#define LLVM_LIBC_UTILS_UNITTEST_ZXTEST_H
#include <zxtest/zxtest.h>
@@ -29,7 +29,12 @@
#endif
namespace LIBC_NAMESPACE::testing {
+
using Test = ::zxtest::Test;
-}
-#endif // LLVM_LIBC_UTILS_UNITTEST_FUCHSIATEST_H
+} // namespace LIBC_NAMESPACE::testing
+
+// zxtest does not have gmock-style matchers.
+#define LIBC_TEST_HAS_MATCHERS() (0)
+
+#endif // LLVM_LIBC_UTILS_UNITTEST_ZXTEST_H
diff --git a/test/include/assert_test.cpp b/test/include/assert_test.cpp
new file mode 100644
index 000000000000..78709bbcdd59
--- /dev/null
+++ b/test/include/assert_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for assert ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "include/llvm-libc-macros/assert-macros.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcAssertTest, VersionMacro) {
+ // 7.2p3 an integer constant expression with a value equivalent to 202311L.
+ EXPECT_EQ(__STDC_VERSION_ASSERT_H__, 202311L);
+}
diff --git a/test/src/fenv/enabled_exceptions_test.cpp b/test/src/fenv/enabled_exceptions_test.cpp
index 53440b704ca7..7d26eab5695b 100644
--- a/test/src/fenv/enabled_exceptions_test.cpp
+++ b/test/src/fenv/enabled_exceptions_test.cpp
@@ -12,15 +12,20 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/macros/properties/architectures.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPExceptMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/fenv_macros.h"
#include <signal.h>
+#include "excepts.h"
+
+using LlvmLibcExceptionStatusTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
+
// This test enables an exception and verifies that raising that exception
// triggers SIGFPE.
-TEST(LlvmLibcExceptionStatusTest, RaiseAndCrash) {
+TEST_F(LlvmLibcExceptionStatusTest, RaiseAndCrash) {
#if defined(LIBC_TARGET_ARCH_IS_ANY_ARM) || \
defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
// Few Arm HW implementations do not trap exceptions. We skip this test
@@ -41,16 +46,7 @@ TEST(LlvmLibcExceptionStatusTest, RaiseAndCrash) {
// that exception handler, so such a testing can be done after we have
// longjmp implemented.
- int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
- FE_UNDERFLOW};
-
- // We '|' the individual exception flags instead of using FE_ALL_EXCEPT
- // as it can include non-standard extensions. Note that we should be able
- // to compile this file with headers from other libcs as well.
- constexpr int ALL_EXCEPTS =
- FE_DIVBYZERO | FE_INVALID | FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW;
-
- for (int e : excepts) {
+ for (int e : EXCEPTS) {
LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);
LIBC_NAMESPACE::fputil::enable_except(e);
ASSERT_EQ(LIBC_NAMESPACE::feclearexcept(FE_ALL_EXCEPT), 0);
diff --git a/test/src/fenv/exception_flags_test.cpp b/test/src/fenv/exception_flags_test.cpp
index 9d2be6426a6d..2f4332df861f 100644
--- a/test/src/fenv/exception_flags_test.cpp
+++ b/test/src/fenv/exception_flags_test.cpp
@@ -12,18 +12,20 @@
#include "src/fenv/fetestexceptflag.h"
#include "src/__support/FPUtil/FEnvImpl.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
-TEST(LlvmLibcFenvTest, GetSetTestExceptFlag) {
+#include "excepts.h"
+
+using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
+
+TEST_F(LlvmLibcFEnvTest, GetSetTestExceptFlag) {
// We will disable all exceptions to prevent invocation of the exception
// handler.
LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
- int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
- FE_UNDERFLOW};
-
- for (int e : excepts) {
+ for (int e : EXCEPTS) {
// The overall idea is to raise an except and save the exception flags.
// Next, clear the flags and then set the saved exception flags. This
// should set the flag corresponding to the previously raised exception.
diff --git a/test/src/fenv/exception_status_test.cpp b/test/src/fenv/exception_status_test.cpp
index a7000020b1a3..fdf942145786 100644
--- a/test/src/fenv/exception_status_test.cpp
+++ b/test/src/fenv/exception_status_test.cpp
@@ -13,24 +13,23 @@
#include "src/fenv/fetestexcept.h"
#include "src/__support/FPUtil/FEnvImpl.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
#include "hdr/fenv_macros.h"
-TEST(LlvmLibcExceptionStatusTest, RaiseAndTest) {
+#include "excepts.h"
+
+using LlvmLibcExceptionStatusTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
+
+TEST_F(LlvmLibcExceptionStatusTest, RaiseAndTest) {
// This test raises a set of exceptions and checks that the exception
// status flags are updated. The intention is really not to invoke the
// exception handler. Hence, we will disable all exceptions at the
// beginning.
LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);
- int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
- FE_UNDERFLOW};
-
- constexpr int ALL_EXCEPTS =
- FE_DIVBYZERO | FE_INVALID | FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW;
-
- for (int e : excepts) {
+ for (int e : EXCEPTS) {
int r = LIBC_NAMESPACE::feraiseexcept(e);
ASSERT_EQ(r, 0);
int s = LIBC_NAMESPACE::fetestexcept(e);
@@ -47,8 +46,8 @@ TEST(LlvmLibcExceptionStatusTest, RaiseAndTest) {
ASSERT_EQ(s, e);
}
- for (int e1 : excepts) {
- for (int e2 : excepts) {
+ for (int e1 : EXCEPTS) {
+ for (int e2 : EXCEPTS) {
int e = e1 | e2;
int r = LIBC_NAMESPACE::feraiseexcept(e);
ASSERT_EQ(r, 0);
@@ -67,9 +66,9 @@ TEST(LlvmLibcExceptionStatusTest, RaiseAndTest) {
}
}
- for (int e1 : excepts) {
- for (int e2 : excepts) {
- for (int e3 : excepts) {
+ for (int e1 : EXCEPTS) {
+ for (int e2 : EXCEPTS) {
+ for (int e3 : EXCEPTS) {
int e = e1 | e2 | e3;
int r = LIBC_NAMESPACE::feraiseexcept(e);
ASSERT_EQ(r, 0);
@@ -89,10 +88,10 @@ TEST(LlvmLibcExceptionStatusTest, RaiseAndTest) {
}
}
- for (int e1 : excepts) {
- for (int e2 : excepts) {
- for (int e3 : excepts) {
- for (int e4 : excepts) {
+ for (int e1 : EXCEPTS) {
+ for (int e2 : EXCEPTS) {
+ for (int e3 : EXCEPTS) {
+ for (int e4 : EXCEPTS) {
int e = e1 | e2 | e3 | e4;
int r = LIBC_NAMESPACE::feraiseexcept(e);
ASSERT_EQ(r, 0);
@@ -113,11 +112,11 @@ TEST(LlvmLibcExceptionStatusTest, RaiseAndTest) {
}
}
- for (int e1 : excepts) {
- for (int e2 : excepts) {
- for (int e3 : excepts) {
- for (int e4 : excepts) {
- for (int e5 : excepts) {
+ for (int e1 : EXCEPTS) {
+ for (int e2 : EXCEPTS) {
+ for (int e3 : EXCEPTS) {
+ for (int e4 : EXCEPTS) {
+ for (int e5 : EXCEPTS) {
int e = e1 | e2 | e3 | e4 | e5;
int r = LIBC_NAMESPACE::feraiseexcept(e);
ASSERT_EQ(r, 0);
diff --git a/test/src/fenv/excepts.h b/test/src/fenv/excepts.h
new file mode 100644
index 000000000000..e9517d319a9b
--- /dev/null
+++ b/test/src/fenv/excepts.h
@@ -0,0 +1,24 @@
+//===-- List of all FE_* constants for tests -----------------------------===//
+//
+// 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
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_SRC_FENV_EXCEPTS_H
+#define LLVM_LIBC_TEST_SRC_FENV_EXCEPTS_H
+
+#include "hdr/fenv_macros.h"
+
+constexpr int EXCEPTS[] = {
+ FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW, FE_UNDERFLOW,
+};
+
+// We '|' the individual exception flags instead of using FE_ALL_EXCEPT
+// as it can include non-standard extensions. Note that we should be able
+// to compile this file with headers from other libcs as well.
+constexpr int ALL_EXCEPTS =
+ FE_DIVBYZERO | FE_INVALID | FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW;
+
+#endif // LLVM_LIBC_TEST_SRC_FENV_EXCEPTS_H
diff --git a/test/src/fenv/feclearexcept_test.cpp b/test/src/fenv/feclearexcept_test.cpp
index bb42d9070358..52adda46adf2 100644
--- a/test/src/fenv/feclearexcept_test.cpp
+++ b/test/src/fenv/feclearexcept_test.cpp
@@ -9,27 +9,30 @@
#include "src/fenv/feclearexcept.h"
#include "src/__support/FPUtil/FEnvImpl.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
#include "hdr/fenv_macros.h"
#include <stdint.h>
-TEST(LlvmLibcFEnvTest, ClearTest) {
- uint16_t excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
- FE_UNDERFLOW};
+#include "excepts.h"
+
+using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
+
+TEST_F(LlvmLibcFEnvTest, ClearTest) {
LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
- for (uint16_t e : excepts)
+ for (int e : EXCEPTS)
ASSERT_EQ(LIBC_NAMESPACE::fputil::test_except(e), 0);
LIBC_NAMESPACE::fputil::raise_except(FE_ALL_EXCEPT);
- for (uint16_t e1 : excepts) {
- for (uint16_t e2 : excepts) {
- for (uint16_t e3 : excepts) {
- for (uint16_t e4 : excepts) {
- for (uint16_t e5 : excepts) {
+ for (int e1 : EXCEPTS) {
+ for (int e2 : EXCEPTS) {
+ for (int e3 : EXCEPTS) {
+ for (int e4 : EXCEPTS) {
+ for (int e5 : EXCEPTS) {
// We clear one exception and test to verify that it was cleared.
LIBC_NAMESPACE::feclearexcept(e1 | e2 | e3 | e4 | e5);
ASSERT_EQ(
diff --git a/test/src/fenv/feenableexcept_test.cpp b/test/src/fenv/feenableexcept_test.cpp
index aeb4f955fd69..232e2a1c8316 100644
--- a/test/src/fenv/feenableexcept_test.cpp
+++ b/test/src/fenv/feenableexcept_test.cpp
@@ -11,11 +11,16 @@
#include "src/fenv/feenableexcept.h"
#include "src/fenv/fegetexcept.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
#include "hdr/fenv_macros.h"
-TEST(LlvmLibcFEnvTest, EnableTest) {
+#include "excepts.h"
+
+using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
+
+TEST_F(LlvmLibcFEnvTest, EnableTest) {
#if defined(LIBC_TARGET_ARCH_IS_ANY_ARM) || \
defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
// Few Arm HW implementations do not trap exceptions. We skip this test
diff --git a/test/src/fenv/feholdexcept_test.cpp b/test/src/fenv/feholdexcept_test.cpp
index 0689d89ab233..f3e05d4a5b6c 100644
--- a/test/src/fenv/feholdexcept_test.cpp
+++ b/test/src/fenv/feholdexcept_test.cpp
@@ -11,10 +11,15 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/macros/properties/architectures.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPExceptMatcher.h"
#include "test/UnitTest/Test.h"
-TEST(LlvmLibcFEnvTest, RaiseAndCrash) {
+#include "excepts.h"
+
+using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
+
+TEST_F(LlvmLibcFEnvTest, RaiseAndCrash) {
#if defined(LIBC_TARGET_ARCH_IS_ANY_ARM) || \
defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
// Few Arm HW implementations do not trap exceptions. We skip this test
diff --git a/test/src/fenv/feupdateenv_test.cpp b/test/src/fenv/feupdateenv_test.cpp
index 251b8566aac3..d2ffc0ef8e84 100644
--- a/test/src/fenv/feupdateenv_test.cpp
+++ b/test/src/fenv/feupdateenv_test.cpp
@@ -10,11 +10,12 @@
#include "src/fenv/feupdateenv.h"
#include "src/__support/FPUtil/FEnvImpl.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
-#include <signal.h>
+using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
-TEST(LlvmLibcFEnvTest, UpdateEnvTest) {
+TEST_F(LlvmLibcFEnvTest, UpdateEnvTest) {
LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
diff --git a/test/src/fenv/getenv_and_setenv_test.cpp b/test/src/fenv/getenv_and_setenv_test.cpp
index f767e8ab9b2f..7257e75cb421 100644
--- a/test/src/fenv/getenv_and_setenv_test.cpp
+++ b/test/src/fenv/getenv_and_setenv_test.cpp
@@ -13,17 +13,19 @@
#include "src/fenv/fesetround.h"
#include "src/__support/FPUtil/FEnvImpl.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
-TEST(LlvmLibcFenvTest, GetEnvAndSetEnv) {
+#include "excepts.h"
+
+using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
+
+TEST_F(LlvmLibcFEnvTest, GetEnvAndSetEnv) {
// We will disable all exceptions to prevent invocation of the exception
// handler.
LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT);
- int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
- FE_UNDERFLOW};
-
- for (int e : excepts) {
+ for (int e : EXCEPTS) {
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
// Save the cleared environment.
@@ -71,7 +73,7 @@ TEST(LlvmLibcFenvTest, Set_FE_DFL_ENV) {
}
#ifdef _WIN32
-TEST(LlvmLibcFenvTest, Windows_Set_Get_Test) {
+TEST_F(LlvmLibcFEnvTest, Windows_Set_Get_Test) {
// If a valid fenv_t is written, then reading it back out should be identical.
fenv_t setEnv = {0x7e00053e, 0x0f00000f};
fenv_t getEnv;
diff --git a/test/src/fenv/rounding_mode_test.cpp b/test/src/fenv/rounding_mode_test.cpp
index ec2e27ecc818..f242ed9aaffe 100644
--- a/test/src/fenv/rounding_mode_test.cpp
+++ b/test/src/fenv/rounding_mode_test.cpp
@@ -9,15 +9,18 @@
#include "src/fenv/fegetround.h"
#include "src/fenv/fesetround.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
#include "hdr/fenv_macros.h"
-TEST(LlvmLibcRoundingModeTest, SetAndGet) {
+using LlvmLibcRoundingModeTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
+
+TEST_F(LlvmLibcRoundingModeTest, SetAndGet) {
struct ResetDefaultRoundingMode {
- int original;
+ int original = LIBC_NAMESPACE::fegetround();
~ResetDefaultRoundingMode() { LIBC_NAMESPACE::fesetround(original); }
- } reset{LIBC_NAMESPACE::fegetround()};
+ } reset;
int s = LIBC_NAMESPACE::fesetround(FE_TONEAREST);
EXPECT_EQ(s, 0);
diff --git a/test/src/math/CeilTest.h b/test/src/math/CeilTest.h
index da3f3c0e8f5a..b4c3752cc5c4 100644
--- a/test/src/math/CeilTest.h
+++ b/test/src/math/CeilTest.h
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -14,7 +15,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class CeilTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class CeilTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/CopySignTest.h b/test/src/math/CopySignTest.h
index 052ff0333438..c66f91477480 100644
--- a/test/src/math/CopySignTest.h
+++ b/test/src/math/CopySignTest.h
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -15,7 +16,7 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
template <typename T>
-class CopySignTest : public LIBC_NAMESPACE::testing::Test {
+class CopySignTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/FAbsTest.h b/test/src/math/FAbsTest.h
index 23ad8a26c481..92b589beeb67 100644
--- a/test/src/math/FAbsTest.h
+++ b/test/src/math/FAbsTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_FABSTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_FABSTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -17,7 +18,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class FAbsTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FAbsTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/FDimTest.h b/test/src/math/FDimTest.h
index 44aba9caf646..fefcefe5052a 100644
--- a/test/src/math/FDimTest.h
+++ b/test/src/math/FDimTest.h
@@ -9,11 +9,12 @@
#include "hdr/math_macros.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class FDimTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
using FuncPtr = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
diff --git a/test/src/math/FMaxTest.h b/test/src/math/FMaxTest.h
index e9857f332e65..405642c6b968 100644
--- a/test/src/math/FMaxTest.h
+++ b/test/src/math/FMaxTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_FMAXTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_FMAXTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -17,7 +18,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class FMaxTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FMaxTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/FMinTest.h b/test/src/math/FMinTest.h
index c6b9f4439b79..eae0008ddfe3 100644
--- a/test/src/math/FMinTest.h
+++ b/test/src/math/FMinTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_FMINTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_FMINTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -17,7 +18,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class FMinTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FMinTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/FModTest.h b/test/src/math/FModTest.h
index bc909987a161..f1015d6497fc 100644
--- a/test/src/math/FModTest.h
+++ b/test/src/math/FModTest.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -24,7 +25,8 @@
#define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, false, 0)
-template <typename T> class FmodTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/FloorTest.h b/test/src/math/FloorTest.h
index 679dc26e1248..9103a5b05eb5 100644
--- a/test/src/math/FloorTest.h
+++ b/test/src/math/FloorTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_FLOORTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_FLOORTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -17,7 +18,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class FloorTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FloorTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/FmaTest.h b/test/src/math/FmaTest.h
index 76bd221fcb1f..5a40f694ebd1 100644
--- a/test/src/math/FmaTest.h
+++ b/test/src/math/FmaTest.h
@@ -12,6 +12,7 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/stdlib/rand.h"
#include "src/stdlib/srand.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -19,7 +20,7 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
template <typename T>
-class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
private:
using Func = T (*)(T, T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
diff --git a/test/src/math/FrexpTest.h b/test/src/math/FrexpTest.h
index 5f993f604999..3ba64afa3c62 100644
--- a/test/src/math/FrexpTest.h
+++ b/test/src/math/FrexpTest.h
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/FPUtil/BasicOperations.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -15,7 +16,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class FrexpTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FrexpTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/HypotTest.h b/test/src/math/HypotTest.h
index 0c15f02fe371..58b533831824 100644
--- a/test/src/math/HypotTest.h
+++ b/test/src/math/HypotTest.h
@@ -10,6 +10,7 @@
#define LLVM_LIBC_TEST_SRC_MATH_HYPOTTEST_H
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -19,7 +20,7 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
template <typename T>
-class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class HypotTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
private:
using Func = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
diff --git a/test/src/math/ILogbTest.h b/test/src/math/ILogbTest.h
index 3d1f047a4806..c2d5a1326e0e 100644
--- a/test/src/math/ILogbTest.h
+++ b/test/src/math/ILogbTest.h
@@ -13,9 +13,10 @@
#include "src/__support/CPP/limits.h" // INT_MAX
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
-class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
+class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
template <typename T> struct ILogbFunc {
typedef int (*Func)(T);
diff --git a/test/src/math/LdExpTest.h b/test/src/math/LdExpTest.h
index 2a406feed52f..34466a526d60 100644
--- a/test/src/math/LdExpTest.h
+++ b/test/src/math/LdExpTest.h
@@ -12,6 +12,7 @@
#include "src/__support/CPP/limits.h" // INT_MAX
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/NormalFloat.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -19,7 +20,7 @@
#include <stdint.h>
template <typename T>
-class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>;
using StorageType = typename FPBits::StorageType;
diff --git a/test/src/math/LogbTest.h b/test/src/math/LogbTest.h
index f066d5f9de02..d6042e3c200c 100644
--- a/test/src/math/LogbTest.h
+++ b/test/src/math/LogbTest.h
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -15,7 +16,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class LogbTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class LogbTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/ModfTest.h b/test/src/math/ModfTest.h
index 49b0328753b3..d6c6f27a5edf 100644
--- a/test/src/math/ModfTest.h
+++ b/test/src/math/ModfTest.h
@@ -8,6 +8,7 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -16,7 +17,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class ModfTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class ModfTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/NextAfterTest.h b/test/src/math/NextAfterTest.h
index a7248dd7042d..b3b03f763992 100644
--- a/test/src/math/NextAfterTest.h
+++ b/test/src/math/NextAfterTest.h
@@ -14,11 +14,12 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
diff --git a/test/src/math/RIntTest.h b/test/src/math/RIntTest.h
index c706ff18f186..007b50427ba3 100644
--- a/test/src/math/RIntTest.h
+++ b/test/src/math/RIntTest.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -25,7 +26,7 @@ static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
FE_TONEAREST};
template <typename T>
-class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class RIntTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
typedef T (*RIntFunc)(T);
diff --git a/test/src/math/RemQuoTest.h b/test/src/math/RemQuoTest.h
index 677772dd9fcc..c39f2394555e 100644
--- a/test/src/math/RemQuoTest.h
+++ b/test/src/math/RemQuoTest.h
@@ -12,6 +12,7 @@
#include "hdr/math_macros.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -19,7 +20,7 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
template <typename T>
-class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
diff --git a/test/src/math/RoundEvenTest.h b/test/src/math/RoundEvenTest.h
index 68b8b9ae1d96..d70555d34765 100644
--- a/test/src/math/RoundEvenTest.h
+++ b/test/src/math/RoundEvenTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_ROUNDEVENTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_ROUNDEVENTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -18,7 +19,7 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
template <typename T>
-class RoundEvenTest : public LIBC_NAMESPACE::testing::Test {
+class RoundEvenTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/RoundTest.h b/test/src/math/RoundTest.h
index eecf95982729..2a31df305ac3 100644
--- a/test/src/math/RoundTest.h
+++ b/test/src/math/RoundTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_ROUNDTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_ROUNDTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -17,7 +18,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class RoundTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class RoundTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/RoundToIntegerTest.h b/test/src/math/RoundToIntegerTest.h
index 7c93451235f2..0f052ba42a46 100644
--- a/test/src/math/RoundToIntegerTest.h
+++ b/test/src/math/RoundToIntegerTest.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -24,7 +25,8 @@ static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
FE_TONEAREST};
template <typename F, typename I, bool TestModes = false>
-class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class RoundToIntegerTestTemplate
+ : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
typedef I (*RoundToIntegerFunc)(F);
@@ -81,6 +83,8 @@ private:
public:
void SetUp() override {
+ LIBC_NAMESPACE::testing::FEnvSafeTest::SetUp();
+
if (math_errhandling & MATH_ERREXCEPT) {
// We will disable all exceptions so that the test will not
// crash with SIGFPE. We can still use fetestexcept to check
diff --git a/test/src/math/SqrtTest.h b/test/src/math/SqrtTest.h
index 799b7862a372..1c422e201bb2 100644
--- a/test/src/math/SqrtTest.h
+++ b/test/src/math/SqrtTest.h
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/CPP/bit.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -15,7 +16,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class SqrtTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class SqrtTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/TruncTest.h b/test/src/math/TruncTest.h
index 57c953fad874..bc5b76131291 100644
--- a/test/src/math/TruncTest.h
+++ b/test/src/math/TruncTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_TRUNCTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_TRUNCTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -17,7 +18,8 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T> class TruncTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class TruncTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/exhaustive/fmod_generic_impl_test.cpp b/test/src/math/exhaustive/fmod_generic_impl_test.cpp
index c7aec5b7bc21..b064b7e37f42 100644
--- a/test/src/math/exhaustive/fmod_generic_impl_test.cpp
+++ b/test/src/math/exhaustive/fmod_generic_impl_test.cpp
@@ -9,6 +9,7 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h" // ldexp
#include "src/__support/FPUtil/generic/FMod.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -18,7 +19,7 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
template <typename T, bool InverseMultiplication>
-class LlvmLibcFModTest : public LIBC_NAMESPACE::testing::Test {
+class LlvmLibcFModTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using U = typename FPBits::StorageType;
diff --git a/test/src/math/smoke/CanonicalizeTest.h b/test/src/math/smoke/CanonicalizeTest.h
index ab45e0eb8e94..7e2456f84705 100644
--- a/test/src/math/smoke/CanonicalizeTest.h
+++ b/test/src/math/smoke/CanonicalizeTest.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/integer_literals.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -26,7 +27,7 @@
using LIBC_NAMESPACE::operator""_u128;
template <typename T>
-class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
+class CanonicalizeTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/CeilTest.h b/test/src/math/smoke/CeilTest.h
index 70e441a849cb..5e108c0e0fee 100644
--- a/test/src/math/smoke/CeilTest.h
+++ b/test/src/math/smoke/CeilTest.h
@@ -9,12 +9,14 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_CEILTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CEILTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
-template <typename T> class CeilTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class CeilTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/CopySignTest.h b/test/src/math/smoke/CopySignTest.h
index fa9da91920f8..1810560bf1bb 100644
--- a/test/src/math/smoke/CopySignTest.h
+++ b/test/src/math/smoke/CopySignTest.h
@@ -9,13 +9,14 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_COPYSIGNTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_COPYSIGNTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
template <typename T>
-class CopySignTest : public LIBC_NAMESPACE::testing::Test {
+class CopySignTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FAbsTest.h b/test/src/math/smoke/FAbsTest.h
index 0c8ca95ba0f7..048023b41429 100644
--- a/test/src/math/smoke/FAbsTest.h
+++ b/test/src/math/smoke/FAbsTest.h
@@ -9,12 +9,14 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FABSTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FABSTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
-template <typename T> class FAbsTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FAbsTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FDimTest.h b/test/src/math/smoke/FDimTest.h
index e557b40d90ef..cff88f29a8ef 100644
--- a/test/src/math/smoke/FDimTest.h
+++ b/test/src/math/smoke/FDimTest.h
@@ -8,11 +8,12 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class FDimTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
using FuncPtr = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
diff --git a/test/src/math/smoke/FMaxTest.h b/test/src/math/smoke/FMaxTest.h
index b8781a85d10f..df8e35e0bd16 100644
--- a/test/src/math/smoke/FMaxTest.h
+++ b/test/src/math/smoke/FMaxTest.h
@@ -9,10 +9,12 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-template <typename T> class FMaxTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FMaxTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMaximumMagNumTest.h b/test/src/math/smoke/FMaximumMagNumTest.h
index 715dd4ed913f..aafb6d2b0d5e 100644
--- a/test/src/math/smoke/FMaximumMagNumTest.h
+++ b/test/src/math/smoke/FMaximumMagNumTest.h
@@ -11,11 +11,12 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FMaximumMagNumTest : public LIBC_NAMESPACE::testing::Test {
+class FMaximumMagNumTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMaximumMagTest.h b/test/src/math/smoke/FMaximumMagTest.h
index 38276e0fe2fd..7bb79a69be58 100644
--- a/test/src/math/smoke/FMaximumMagTest.h
+++ b/test/src/math/smoke/FMaximumMagTest.h
@@ -10,11 +10,12 @@
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUM_MAGTEST_H
#include "src/__support/FPUtil/BasicOperations.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FMaximumMagTest : public LIBC_NAMESPACE::testing::Test {
+class FMaximumMagTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMaximumNumTest.h b/test/src/math/smoke/FMaximumNumTest.h
index 57096f6b614a..da0ea2c247a9 100644
--- a/test/src/math/smoke/FMaximumNumTest.h
+++ b/test/src/math/smoke/FMaximumNumTest.h
@@ -10,11 +10,12 @@
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMNUMTEST_H
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FMaximumNumTest : public LIBC_NAMESPACE::testing::Test {
+class FMaximumNumTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMaximumTest.h b/test/src/math/smoke/FMaximumTest.h
index 4db8bb93baae..1bd15163ed75 100644
--- a/test/src/math/smoke/FMaximumTest.h
+++ b/test/src/math/smoke/FMaximumTest.h
@@ -9,11 +9,12 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FMaximumTest : public LIBC_NAMESPACE::testing::Test {
+class FMaximumTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMinTest.h b/test/src/math/smoke/FMinTest.h
index b1ffe38829f4..f71b558cd3da 100644
--- a/test/src/math/smoke/FMinTest.h
+++ b/test/src/math/smoke/FMinTest.h
@@ -9,10 +9,12 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-template <typename T> class FMinTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FMinTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMinimumMagNumTest.h b/test/src/math/smoke/FMinimumMagNumTest.h
index dec8b70740ca..e4b8fd9e3353 100644
--- a/test/src/math/smoke/FMinimumMagNumTest.h
+++ b/test/src/math/smoke/FMinimumMagNumTest.h
@@ -11,11 +11,12 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FMinimumMagNumTest : public LIBC_NAMESPACE::testing::Test {
+class FMinimumMagNumTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMinimumMagTest.h b/test/src/math/smoke/FMinimumMagTest.h
index b11092e5379b..3e16622fe3fa 100644
--- a/test/src/math/smoke/FMinimumMagTest.h
+++ b/test/src/math/smoke/FMinimumMagTest.h
@@ -10,11 +10,12 @@
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUM_MAGTEST_H
#include "src/__support/FPUtil/BasicOperations.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FMinimumMagTest : public LIBC_NAMESPACE::testing::Test {
+class FMinimumMagTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMinimumNumTest.h b/test/src/math/smoke/FMinimumNumTest.h
index 7fcc291b4c00..6186ea0df17c 100644
--- a/test/src/math/smoke/FMinimumNumTest.h
+++ b/test/src/math/smoke/FMinimumNumTest.h
@@ -10,11 +10,12 @@
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMNUMTEST_H
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FMinimumNumTest : public LIBC_NAMESPACE::testing::Test {
+class FMinimumNumTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FMinimumTest.h b/test/src/math/smoke/FMinimumTest.h
index bc04a6d99356..a267f6c78321 100644
--- a/test/src/math/smoke/FMinimumTest.h
+++ b/test/src/math/smoke/FMinimumTest.h
@@ -9,11 +9,12 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FMinimumTest : public LIBC_NAMESPACE::testing::Test {
+class FMinimumTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FModTest.h b/test/src/math/smoke/FModTest.h
index bc909987a161..f1015d6497fc 100644
--- a/test/src/math/smoke/FModTest.h
+++ b/test/src/math/smoke/FModTest.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -24,7 +25,8 @@
#define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, false, 0)
-template <typename T> class FmodTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FloorTest.h b/test/src/math/smoke/FloorTest.h
index 12944aa77562..b2102459bc3d 100644
--- a/test/src/math/smoke/FloorTest.h
+++ b/test/src/math/smoke/FloorTest.h
@@ -9,12 +9,14 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_FLOORTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FLOORTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
-template <typename T> class FloorTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FloorTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FmaTest.h b/test/src/math/smoke/FmaTest.h
index c66035927d98..7063ecf19983 100644
--- a/test/src/math/smoke/FmaTest.h
+++ b/test/src/math/smoke/FmaTest.h
@@ -10,11 +10,12 @@
#define LLVM_LIBC_TEST_SRC_MATH_FMATEST_H
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
private:
using Func = T (*)(T, T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
diff --git a/test/src/math/smoke/FrexpTest.h b/test/src/math/smoke/FrexpTest.h
index bf99a9a559f0..e9e496422f73 100644
--- a/test/src/math/smoke/FrexpTest.h
+++ b/test/src/math/smoke/FrexpTest.h
@@ -7,10 +7,12 @@
//===----------------------------------------------------------------------===//
#include "src/__support/FPUtil/BasicOperations.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-template <typename T> class FrexpTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class FrexpTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FromfpTest.h b/test/src/math/smoke/FromfpTest.h
index d3a61baafda1..f19f21ce47e7 100644
--- a/test/src/math/smoke/FromfpTest.h
+++ b/test/src/math/smoke/FromfpTest.h
@@ -9,11 +9,12 @@
#ifndef LIBC_TEST_SRC_MATH_SMOKE_FROMFPTEST_H
#define LIBC_TEST_SRC_MATH_SMOKE_FROMFPTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FromfpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/FromfpxTest.h b/test/src/math/smoke/FromfpxTest.h
index f3a1680b05aa..4aa47a68bb17 100644
--- a/test/src/math/smoke/FromfpxTest.h
+++ b/test/src/math/smoke/FromfpxTest.h
@@ -9,11 +9,12 @@
#ifndef LIBC_TEST_SRC_MATH_SMOKE_FROMFPXTEST_H
#define LIBC_TEST_SRC_MATH_SMOKE_FROMFPXTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/HypotTest.h b/test/src/math/smoke/HypotTest.h
index a1b8f8a7fafa..80e9bb7366df 100644
--- a/test/src/math/smoke/HypotTest.h
+++ b/test/src/math/smoke/HypotTest.h
@@ -10,13 +10,14 @@
#define LLVM_LIBC_TEST_SRC_MATH_HYPOTTEST_H
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
template <typename T>
-class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class HypotTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
private:
using Func = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
diff --git a/test/src/math/smoke/ILogbTest.h b/test/src/math/smoke/ILogbTest.h
index bb5bc33b6b3a..05f906b69947 100644
--- a/test/src/math/smoke/ILogbTest.h
+++ b/test/src/math/smoke/ILogbTest.h
@@ -12,10 +12,11 @@
#include "src/__support/CPP/limits.h" // INT_MAX
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/Test.h"
template <typename OutType, typename InType>
-class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
+class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<InType>;
using StorageType = typename FPBits::StorageType;
diff --git a/test/src/math/smoke/LdExpTest.h b/test/src/math/smoke/LdExpTest.h
index c3e852a2a473..713d305c4749 100644
--- a/test/src/math/smoke/LdExpTest.h
+++ b/test/src/math/smoke/LdExpTest.h
@@ -12,13 +12,14 @@
#include "src/__support/CPP/limits.h" // INT_MAX
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/NormalFloat.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include <stdint.h>
template <typename T>
-class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>;
using StorageType = typename FPBits::StorageType;
diff --git a/test/src/math/smoke/LogbTest.h b/test/src/math/smoke/LogbTest.h
index 01e1050b4c4f..4938fcf8f6f1 100644
--- a/test/src/math/smoke/LogbTest.h
+++ b/test/src/math/smoke/LogbTest.h
@@ -7,10 +7,12 @@
//===----------------------------------------------------------------------===//
#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-template <typename T> class LogbTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class LogbTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/ModfTest.h b/test/src/math/smoke/ModfTest.h
index 65d61855c9f2..85db2d6d967b 100644
--- a/test/src/math/smoke/ModfTest.h
+++ b/test/src/math/smoke/ModfTest.h
@@ -8,12 +8,14 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
-template <typename T> class ModfTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class ModfTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/NextAfterTest.h b/test/src/math/smoke/NextAfterTest.h
index d9c50c8109d8..65dba9338285 100644
--- a/test/src/math/smoke/NextAfterTest.h
+++ b/test/src/math/smoke/NextAfterTest.h
@@ -14,6 +14,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -29,7 +30,7 @@
ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_OVERFLOW)
template <typename T>
-class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
diff --git a/test/src/math/smoke/NextDownTest.h b/test/src/math/smoke/NextDownTest.h
index c678ab1db1de..b54c6d576322 100644
--- a/test/src/math/smoke/NextDownTest.h
+++ b/test/src/math/smoke/NextDownTest.h
@@ -9,11 +9,12 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTDOWNTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_NEXTDOWNTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class NextDownTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class NextDownTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/NextTowardTest.h b/test/src/math/smoke/NextTowardTest.h
index b6c1c8d1797d..1894d324b085 100644
--- a/test/src/math/smoke/NextTowardTest.h
+++ b/test/src/math/smoke/NextTowardTest.h
@@ -15,6 +15,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -30,7 +31,7 @@
ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_OVERFLOW)
template <typename T>
-class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using ToFPBits = LIBC_NAMESPACE::fputil::FPBits<long double>;
using StorageType = typename FPBits::StorageType;
diff --git a/test/src/math/smoke/NextUpTest.h b/test/src/math/smoke/NextUpTest.h
index ebbdb5c73def..7f66c115dfc2 100644
--- a/test/src/math/smoke/NextUpTest.h
+++ b/test/src/math/smoke/NextUpTest.h
@@ -9,11 +9,12 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTUPTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_NEXTUPTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class NextUpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class NextUpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/RIntTest.h b/test/src/math/smoke/RIntTest.h
index cbed9a3b10ba..1412c3f27a2d 100644
--- a/test/src/math/smoke/RIntTest.h
+++ b/test/src/math/smoke/RIntTest.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -22,7 +23,7 @@ static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
FE_TONEAREST};
template <typename T>
-class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class RIntTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
typedef T (*RIntFunc)(T);
diff --git a/test/src/math/smoke/RemQuoTest.h b/test/src/math/smoke/RemQuoTest.h
index 7df537d8b206..43eee3d38e44 100644
--- a/test/src/math/smoke/RemQuoTest.h
+++ b/test/src/math/smoke/RemQuoTest.h
@@ -12,11 +12,12 @@
#include "hdr/math_macros.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
diff --git a/test/src/math/smoke/RoundEvenTest.h b/test/src/math/smoke/RoundEvenTest.h
index e168d57bdbf3..479b70912fed 100644
--- a/test/src/math/smoke/RoundEvenTest.h
+++ b/test/src/math/smoke/RoundEvenTest.h
@@ -9,13 +9,14 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDEVENTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDEVENTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
template <typename T>
-class RoundEvenTest : public LIBC_NAMESPACE::testing::Test {
+class RoundEvenTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/RoundTest.h b/test/src/math/smoke/RoundTest.h
index 49b2a1bf7dfb..36994f27eb4c 100644
--- a/test/src/math/smoke/RoundTest.h
+++ b/test/src/math/smoke/RoundTest.h
@@ -9,12 +9,14 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
-template <typename T> class RoundTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class RoundTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/RoundToIntegerTest.h b/test/src/math/smoke/RoundToIntegerTest.h
index 863cf75f05ff..50bcd4a6a76c 100644
--- a/test/src/math/smoke/RoundToIntegerTest.h
+++ b/test/src/math/smoke/RoundToIntegerTest.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -21,7 +22,8 @@ static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
FE_TONEAREST};
template <typename F, typename I, bool TestModes = false>
-class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class RoundToIntegerTestTemplate
+ : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
typedef I (*RoundToIntegerFunc)(F);
@@ -61,6 +63,8 @@ private:
public:
void SetUp() override {
+ LIBC_NAMESPACE::testing::FEnvSafeTest::SetUp();
+
if (math_errhandling & MATH_ERREXCEPT) {
// We will disable all exceptions so that the test will not
// crash with SIGFPE. We can still use fetestexcept to check
diff --git a/test/src/math/smoke/SqrtTest.h b/test/src/math/smoke/SqrtTest.h
index 46382ed58e14..8afacaf01ae4 100644
--- a/test/src/math/smoke/SqrtTest.h
+++ b/test/src/math/smoke/SqrtTest.h
@@ -7,12 +7,14 @@
//===----------------------------------------------------------------------===//
#include "src/__support/CPP/bit.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
-template <typename T> class SqrtTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class SqrtTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/TruncTest.h b/test/src/math/smoke/TruncTest.h
index c0fc87f9313b..1d9c44dfb374 100644
--- a/test/src/math/smoke/TruncTest.h
+++ b/test/src/math/smoke/TruncTest.h
@@ -9,12 +9,14 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_TRUNCTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_TRUNCTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
-template <typename T> class TruncTest : public LIBC_NAMESPACE::testing::Test {
+template <typename T>
+class TruncTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/UfromfpTest.h b/test/src/math/smoke/UfromfpTest.h
index 9ad1e6dce945..1c04049ebb4f 100644
--- a/test/src/math/smoke/UfromfpTest.h
+++ b/test/src/math/smoke/UfromfpTest.h
@@ -9,11 +9,12 @@
#ifndef LIBC_TEST_SRC_MATH_SMOKE_UFROMFPTEST_H
#define LIBC_TEST_SRC_MATH_SMOKE_UFROMFPTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/UfromfpxTest.h b/test/src/math/smoke/UfromfpxTest.h
index 09163b8adfa5..973bc8a4d1be 100644
--- a/test/src/math/smoke/UfromfpxTest.h
+++ b/test/src/math/smoke/UfromfpxTest.h
@@ -9,11 +9,12 @@
#ifndef LIBC_TEST_SRC_MATH_SMOKE_UFROMFPXTEST_H
#define LIBC_TEST_SRC_MATH_SMOKE_UFROMFPXTEST_H
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
-class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::Test {
+class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
diff --git a/test/src/math/smoke/nan_test.cpp b/test/src/math/smoke/nan_test.cpp
index 56c1e9164df4..2ddef5832567 100644
--- a/test/src/math/smoke/nan_test.cpp
+++ b/test/src/math/smoke/nan_test.cpp
@@ -8,11 +8,12 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/nan.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include <signal.h>
-class LlvmLibcNanTest : public LIBC_NAMESPACE::testing::Test {
+class LlvmLibcNanTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
using StorageType = LIBC_NAMESPACE::fputil::FPBits<double>::StorageType;
diff --git a/test/src/math/smoke/nanf128_test.cpp b/test/src/math/smoke/nanf128_test.cpp
index 652e35ccb53d..8c15c532ebcf 100644
--- a/test/src/math/smoke/nanf128_test.cpp
+++ b/test/src/math/smoke/nanf128_test.cpp
@@ -9,10 +9,11 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/uint128.h"
#include "src/math/nanf128.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-class LlvmLibcNanf128Test : public LIBC_NAMESPACE::testing::Test {
+class LlvmLibcNanf128Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
using FPBits128 = LIBC_NAMESPACE::fputil::FPBits<float128>;
using StorageType = FPBits128::StorageType;
diff --git a/test/src/math/smoke/nanf_test.cpp b/test/src/math/smoke/nanf_test.cpp
index bce495f1a973..71f888c610aa 100644
--- a/test/src/math/smoke/nanf_test.cpp
+++ b/test/src/math/smoke/nanf_test.cpp
@@ -8,11 +8,12 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/nanf.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include <signal.h>
-class LlvmLibcNanfTest : public LIBC_NAMESPACE::testing::Test {
+class LlvmLibcNanfTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
using StorageType = LIBC_NAMESPACE::fputil::FPBits<float>::StorageType;
diff --git a/test/src/math/smoke/nanl_test.cpp b/test/src/math/smoke/nanl_test.cpp
index 5ff70a94b54d..7fff20b1e7be 100644
--- a/test/src/math/smoke/nanl_test.cpp
+++ b/test/src/math/smoke/nanl_test.cpp
@@ -8,6 +8,7 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/nanl.h"
+#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include <signal.h>
@@ -22,7 +23,7 @@
#error "Unknown long double type"
#endif
-class LlvmLibcNanlTest : public LIBC_NAMESPACE::testing::Test {
+class LlvmLibcNanlTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
using StorageType = LIBC_NAMESPACE::fputil::FPBits<long double>::StorageType;
diff --git a/test/src/pthread/pthread_rwlockattr_test.cpp b/test/src/pthread/pthread_rwlockattr_test.cpp
new file mode 100644
index 000000000000..6e5ae70df734
--- /dev/null
+++ b/test/src/pthread/pthread_rwlockattr_test.cpp
@@ -0,0 +1,64 @@
+//===-- Unittests for pthread_rwlockattr_t --------------------------------===//
+//
+// 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 "include/llvm-libc-macros/generic-error-number-macros.h" // EINVAL
+#include "src/pthread/pthread_rwlockattr_destroy.h"
+#include "src/pthread/pthread_rwlockattr_getpshared.h"
+#include "src/pthread/pthread_rwlockattr_init.h"
+#include "src/pthread/pthread_rwlockattr_setpshared.h"
+#include "test/UnitTest/Test.h"
+
+// TODO: https://github.com/llvm/llvm-project/issues/88997
+#include <pthread.h> // PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED
+
+TEST(LlvmLibcPThreadRWLockAttrTest, InitAndDestroy) {
+ pthread_rwlockattr_t attr;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0);
+}
+
+TEST(LlvmLibcPThreadRWLockAttrTest, GetDefaultValues) {
+ pthread_rwlockattr_t attr;
+
+ // Invalid value.
+ int pshared = 42;
+
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0);
+ ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0);
+}
+
+TEST(LlvmLibcPThreadRWLockAttrTest, SetGoodValues) {
+ pthread_rwlockattr_t attr;
+
+ // Invalid value.
+ int pshared = 42;
+
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setpshared(
+ &attr, PTHREAD_PROCESS_SHARED),
+ 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0);
+ ASSERT_EQ(pshared, PTHREAD_PROCESS_SHARED);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0);
+}
+
+TEST(LlvmLibcPThreadRWLockAttrTest, SetBadValues) {
+ pthread_rwlockattr_t attr;
+
+ // Invalid value.
+ int pshared = 42;
+
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setpshared(&attr, pshared),
+ EINVAL);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0);
+ ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0);
+}