llvm-project/libc/test/UnitTest/FPExceptMatcher.cpp
Nick Desaulniers e566313a1f
[libc][signal] clean up usage of sighandler_t (#125745)
`man 3 signal`'s declaration has a face _only a mother could love_.

sighandler_t and __sighandler_t are not defined in the C standard, or POSIX.

They are helpful typedefs provided by glibc and the Linux kernel UAPI headers
respectively since working with function pointers' syntax can be painful. But
we should not rely on them; in C++ we have `auto*` and `using` statements.

Remove the proxy header, and only include a typedef for sighandler_t when
targeting Linux, for compatibility with glibc.

Fixes: #125598
2025-02-07 10:43:56 -08:00

59 lines
1.6 KiB
C++

//===-- FPExceptMatchers.cpp ----------------------------------------------===//
//
// 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 "FPExceptMatcher.h"
#include "src/__support/macros/config.h"
#include "test/UnitTest/ExecuteFunction.h" // FunctionCaller
#include "test/UnitTest/Test.h"
#include "hdr/types/fenv_t.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include <setjmp.h>
#include <signal.h>
#if LIBC_TEST_HAS_MATCHERS()
namespace LIBC_NAMESPACE_DECL {
namespace testing {
#if defined(_WIN32)
#define sigjmp_buf jmp_buf
#define sigsetjmp(buf, save) setjmp(buf)
#define siglongjmp(buf, val) longjmp(buf, val)
#endif
static thread_local sigjmp_buf jumpBuffer;
static thread_local bool caughtExcept;
static void sigfpeHandler(int sig) {
caughtExcept = true;
siglongjmp(jumpBuffer, -1);
}
FPExceptMatcher::FPExceptMatcher(FunctionCaller *func) {
auto *oldSIGFPEHandler = signal(SIGFPE, &sigfpeHandler);
caughtExcept = false;
fenv_t oldEnv;
fputil::get_env(&oldEnv);
if (sigsetjmp(jumpBuffer, 1) == 0)
func->call();
delete func;
// We restore the previous floating point environment after
// the call to the function which can potentially raise SIGFPE.
fputil::set_env(&oldEnv);
signal(SIGFPE, oldSIGFPEHandler);
exceptionRaised = caughtExcept;
}
} // namespace testing
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TEST_HAS_MATCHERS()