forked from OSchip/llvm-project
[libc] Move FPExceptMatcher out of TestHelpers.h
TestHelpers.h pulls few pieces from LLVM libc's unittest framework which aren't available on platforms like Fuchsia which use their own unittest framework. So, by moving FPExceptMatcher to a different file we can exclude LLVM libc specific pieces in a cleaner way. In a later pass, it might make more sense to rename TestHelpers.h also to FPMatcher.h. That way, we can make macros like EXPECT_FP_EQ to be equivalent to EXPECT_EQ on platforms like Fuchsia. Reviewed By: michaelrj Differential Revision: https://reviews.llvm.org/D107129
This commit is contained in:
parent
f08229f49e
commit
3d758e68a7
|
@ -11,7 +11,7 @@
|
|||
#include "src/fenv/fetestexcept.h"
|
||||
|
||||
#include "utils/FPUtil/FEnvUtils.h"
|
||||
#include "utils/FPUtil/TestHelpers.h"
|
||||
#include "utils/FPUtil/FPExceptMatcher.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
#include <fenv.h>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "src/fenv/feholdexcept.h"
|
||||
|
||||
#include "utils/FPUtil/FEnvUtils.h"
|
||||
#include "utils/FPUtil/TestHelpers.h"
|
||||
#include "utils/FPUtil/FPExceptMatcher.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
#include <fenv.h>
|
||||
|
|
|
@ -36,6 +36,8 @@ add_header_library(
|
|||
|
||||
add_library(
|
||||
LibcFPTestHelpers
|
||||
FPExceptMatcher.cpp
|
||||
FPExceptMatcher.h
|
||||
TestHelpers.cpp
|
||||
TestHelpers.h
|
||||
)
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
//===-- 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 <fenv.h>
|
||||
#include <memory>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace fputil {
|
||||
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);
|
||||
std::unique_ptr<FunctionCaller> funcUP(func);
|
||||
|
||||
caughtExcept = false;
|
||||
fenv_t oldEnv;
|
||||
fegetenv(&oldEnv);
|
||||
if (sigsetjmp(jumpBuffer, 1) == 0)
|
||||
funcUP->call();
|
||||
// We restore the previous floating point environment after
|
||||
// the call to the function which can potentially raise SIGFPE.
|
||||
fesetenv(&oldEnv);
|
||||
signal(SIGFPE, oldSIGFPEHandler);
|
||||
exceptionRaised = caughtExcept;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace fputil
|
||||
} // namespace __llvm_libc
|
|
@ -0,0 +1,67 @@
|
|||
//===-- FPExceptMatcher.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_UTILS_FPUTIL_FP_EXCEPT_MATCHER_H
|
||||
#define LLVM_LIBC_UTILS_FPUTIL_FP_EXCEPT_MATCHER_H
|
||||
|
||||
#ifndef LLVM_LIBC_TEST_USE_FUCHSIA
|
||||
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace fputil {
|
||||
namespace testing {
|
||||
|
||||
// TODO: Make the matcher match specific exceptions instead of just identifying
|
||||
// that an exception was raised.
|
||||
class FPExceptMatcher : public __llvm_libc::testing::Matcher<bool> {
|
||||
bool exceptionRaised;
|
||||
|
||||
public:
|
||||
class FunctionCaller {
|
||||
public:
|
||||
virtual ~FunctionCaller(){};
|
||||
virtual void call() = 0;
|
||||
};
|
||||
|
||||
template <typename Func> static FunctionCaller *getFunctionCaller(Func func) {
|
||||
struct Callable : public FunctionCaller {
|
||||
Func f;
|
||||
explicit Callable(Func theFunc) : f(theFunc) {}
|
||||
void call() override { f(); }
|
||||
};
|
||||
|
||||
return new Callable(func);
|
||||
}
|
||||
|
||||
// Takes ownership of func.
|
||||
explicit FPExceptMatcher(FunctionCaller *func);
|
||||
|
||||
bool match(bool unused) { return exceptionRaised; }
|
||||
|
||||
void explainError(testutils::StreamWrapper &stream) override {
|
||||
stream << "A floating point exception should have been raised but it "
|
||||
<< "wasn't\n";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
} // namespace fputil
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#define ASSERT_RAISES_FP_EXCEPT(func) \
|
||||
ASSERT_THAT( \
|
||||
true, \
|
||||
__llvm_libc::fputil::testing::FPExceptMatcher( \
|
||||
__llvm_libc::fputil::testing::FPExceptMatcher::getFunctionCaller( \
|
||||
func)))
|
||||
#else
|
||||
#define ASSERT_RAISES_FP_EXCEPT(func) ASSERT_DEATH(func, WITH_SIGNAL(SIGFPE))
|
||||
#endif // LLVM_LIBC_TEST_USE_FUCHSIA
|
||||
|
||||
#endif // LLVM_LIBC_UTILS_FPUTIL_FP_EXCEPT_MATCHER_H
|
|
@ -10,10 +10,6 @@
|
|||
|
||||
#include "FPBits.h"
|
||||
|
||||
#include <fenv.h>
|
||||
#include <memory>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <string>
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
@ -74,36 +70,6 @@ template void describeValue<double>(const char *, double,
|
|||
template void describeValue<long double>(const char *, long double,
|
||||
testutils::StreamWrapper &);
|
||||
|
||||
#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);
|
||||
std::unique_ptr<FunctionCaller> funcUP(func);
|
||||
|
||||
caughtExcept = false;
|
||||
fenv_t oldEnv;
|
||||
fegetenv(&oldEnv);
|
||||
if (sigsetjmp(jumpBuffer, 1) == 0)
|
||||
funcUP->call();
|
||||
// We restore the previous floating point environment after
|
||||
// the call to the function which can potentially raise SIGFPE.
|
||||
fesetenv(&oldEnv);
|
||||
signal(SIGFPE, oldSIGFPEHandler);
|
||||
exceptionRaised = caughtExcept;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace fputil
|
||||
} // namespace __llvm_libc
|
||||
|
|
|
@ -61,39 +61,6 @@ FPMatcher<T, C> getMatcher(T expectedValue) {
|
|||
return FPMatcher<T, C>(expectedValue);
|
||||
}
|
||||
|
||||
// TODO: Make the matcher match specific exceptions instead of just identifying
|
||||
// that an exception was raised.
|
||||
class FPExceptMatcher : public __llvm_libc::testing::Matcher<bool> {
|
||||
bool exceptionRaised;
|
||||
|
||||
public:
|
||||
class FunctionCaller {
|
||||
public:
|
||||
virtual ~FunctionCaller(){};
|
||||
virtual void call() = 0;
|
||||
};
|
||||
|
||||
template <typename Func> static FunctionCaller *getFunctionCaller(Func func) {
|
||||
struct Callable : public FunctionCaller {
|
||||
Func f;
|
||||
explicit Callable(Func theFunc) : f(theFunc) {}
|
||||
void call() override { f(); }
|
||||
};
|
||||
|
||||
return new Callable(func);
|
||||
}
|
||||
|
||||
// Takes ownership of func.
|
||||
explicit FPExceptMatcher(FunctionCaller *func);
|
||||
|
||||
bool match(bool unused) { return exceptionRaised; }
|
||||
|
||||
void explainError(testutils::StreamWrapper &stream) override {
|
||||
stream << "A floating point exception should have been raised but it "
|
||||
<< "wasn't\n";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
} // namespace fputil
|
||||
} // namespace __llvm_libc
|
||||
|
@ -131,15 +98,4 @@ public:
|
|||
__llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_NE>( \
|
||||
expected))
|
||||
|
||||
#ifdef LLVM_LIBC_TEST_USE_FUCHSIA
|
||||
#define ASSERT_RAISES_FP_EXCEPT(func) ASSERT_DEATH(func, WITH_SIGNAL(SIGFPE))
|
||||
#else
|
||||
#define ASSERT_RAISES_FP_EXCEPT(func) \
|
||||
ASSERT_THAT( \
|
||||
true, \
|
||||
__llvm_libc::fputil::testing::FPExceptMatcher( \
|
||||
__llvm_libc::fputil::testing::FPExceptMatcher::getFunctionCaller( \
|
||||
func)))
|
||||
#endif // LLVM_LIBC_TEST_USE_FUCHSIA
|
||||
|
||||
#endif // LLVM_LIBC_UTILS_FPUTIL_TEST_HELPERS_H
|
||||
|
|
Loading…
Reference in New Issue