59 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "FPExceptMatcher.h"10 11#include "src/__support/macros/config.h"12#include "test/UnitTest/ExecuteFunction.h" // FunctionCaller13#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_buf27#define sigsetjmp(buf, save) setjmp(buf)28#define siglongjmp(buf, val) longjmp(buf, val)29#endif30 31static thread_local sigjmp_buf jumpBuffer;32static thread_local bool caughtExcept;33 34static void sigfpeHandler([[maybe_unused]] 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 after49 // 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 testing56} // namespace LIBC_NAMESPACE_DECL57 58#endif // LIBC_TEST_HAS_MATCHERS()59