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//===----------------------------------------------------------------------===//
8
9#include "FPExceptMatcher.h"
10
11#include "src/__support/macros/config.h"
12#include "test/UnitTest/ExecuteFunction.h" // FunctionCaller
13#include "test/UnitTest/Test.h"
14
15#include "hdr/types/fenv_t.h"
16#include "src/__support/FPUtil/FEnvImpl.h"
17#include <setjmp.h>
18#include <signal.h>
19
20#if LIBC_TEST_HAS_MATCHERS()
21
22namespace LIBC_NAMESPACE_DECL {
23namespace testing {
24
25#if defined(_WIN32)
26#define sigjmp_buf jmp_buf
27#define sigsetjmp(buf, save) setjmp(buf)
28#define siglongjmp(buf, val) longjmp(buf, val)
29#endif
30
31static thread_local sigjmp_buf jumpBuffer;
32static thread_local bool caughtExcept;
33
34static void sigfpeHandler(int sig) {
35 caughtExcept = true;
36 siglongjmp(jumpBuffer, -1);
37}
38
39FPExceptMatcher::FPExceptMatcher(FunctionCaller *func) {
40 auto *oldSIGFPEHandler = signal(SIGFPE, &sigfpeHandler);
41
42 caughtExcept = false;
43 fenv_t oldEnv;
44 fputil::get_env(&oldEnv);
45 if (sigsetjmp(jumpBuffer, 1) == 0)
46 func->call();
47 delete func;
48 // We restore the previous floating point environment after
49 // the call to the function which can potentially raise SIGFPE.
50 fputil::set_env(&oldEnv);
51 signal(SIGFPE, oldSIGFPEHandler);
52 exceptionRaised = caughtExcept;
53}
54
55} // namespace testing
56} // namespace LIBC_NAMESPACE_DECL
57
58#endif // LIBC_TEST_HAS_MATCHERS()
59

source code of libc/test/UnitTest/FPExceptMatcher.cpp