Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libc / test / UnitTest / FPExceptMatcher.cpp
blob1601b7e53f2be1b968db601bb362bcdc2f78fe57
1 //===-- FPExceptMatchers.cpp ----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "FPExceptMatcher.h"
11 #include <fenv.h>
12 #include <memory>
13 #include <setjmp.h>
14 #include <signal.h>
16 namespace LIBC_NAMESPACE {
17 namespace testing {
19 #if defined(_WIN32)
20 #define sigjmp_buf jmp_buf
21 #define sigsetjmp(buf, save) setjmp(buf)
22 #define siglongjmp(buf, val) longjmp(buf, val)
23 #endif
25 static thread_local sigjmp_buf jumpBuffer;
26 static thread_local bool caughtExcept;
28 static void sigfpeHandler(int sig) {
29 caughtExcept = true;
30 siglongjmp(jumpBuffer, -1);
33 FPExceptMatcher::FPExceptMatcher(FunctionCaller *func) {
34 auto oldSIGFPEHandler = signal(SIGFPE, &sigfpeHandler);
35 std::unique_ptr<FunctionCaller> funcUP(func);
37 caughtExcept = false;
38 fenv_t oldEnv;
39 fegetenv(&oldEnv);
40 if (sigsetjmp(jumpBuffer, 1) == 0)
41 funcUP->call();
42 // We restore the previous floating point environment after
43 // the call to the function which can potentially raise SIGFPE.
44 fesetenv(&oldEnv);
45 signal(SIGFPE, oldSIGFPEHandler);
46 exceptionRaised = caughtExcept;
49 } // namespace testing
50 } // namespace LIBC_NAMESPACE