1af1315c2SSiva Chandra Reddy //===-- FPExceptMatchers.cpp ----------------------------------------------===// 2af1315c2SSiva Chandra Reddy // 3af1315c2SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4af1315c2SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information. 5af1315c2SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6af1315c2SSiva Chandra Reddy // 7af1315c2SSiva Chandra Reddy //===----------------------------------------------------------------------===// 8af1315c2SSiva Chandra Reddy 9af1315c2SSiva Chandra Reddy #include "FPExceptMatcher.h" 10af1315c2SSiva Chandra Reddy 115ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 120efb376cSNick Desaulniers #include "test/UnitTest/ExecuteFunction.h" // FunctionCaller 13d2be9826SRoland McGrath #include "test/UnitTest/Test.h" 14d2be9826SRoland McGrath 1575bbf4ddSJob Henandez Lara #include "hdr/types/fenv_t.h" 1675bbf4ddSJob Henandez Lara #include "src/__support/FPUtil/FEnvImpl.h" 17af1315c2SSiva Chandra Reddy #include <setjmp.h> 18af1315c2SSiva Chandra Reddy #include <signal.h> 19af1315c2SSiva Chandra Reddy 20d2be9826SRoland McGrath #if LIBC_TEST_HAS_MATCHERS() 21d2be9826SRoland McGrath 225ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 23af1315c2SSiva Chandra Reddy namespace testing { 24af1315c2SSiva Chandra Reddy 25af1315c2SSiva Chandra Reddy #if defined(_WIN32) 26af1315c2SSiva Chandra Reddy #define sigjmp_buf jmp_buf 27af1315c2SSiva Chandra Reddy #define sigsetjmp(buf, save) setjmp(buf) 28af1315c2SSiva Chandra Reddy #define siglongjmp(buf, val) longjmp(buf, val) 29af1315c2SSiva Chandra Reddy #endif 30af1315c2SSiva Chandra Reddy 31af1315c2SSiva Chandra Reddy static thread_local sigjmp_buf jumpBuffer; 32af1315c2SSiva Chandra Reddy static thread_local bool caughtExcept; 33af1315c2SSiva Chandra Reddy 34af1315c2SSiva Chandra Reddy static void sigfpeHandler(int sig) { 35af1315c2SSiva Chandra Reddy caughtExcept = true; 36af1315c2SSiva Chandra Reddy siglongjmp(jumpBuffer, -1); 37af1315c2SSiva Chandra Reddy } 38af1315c2SSiva Chandra Reddy 39af1315c2SSiva Chandra Reddy FPExceptMatcher::FPExceptMatcher(FunctionCaller *func) { 400efb376cSNick Desaulniers sighandler_t oldSIGFPEHandler = signal(SIGFPE, &sigfpeHandler); 41af1315c2SSiva Chandra Reddy 42af1315c2SSiva Chandra Reddy caughtExcept = false; 43af1315c2SSiva Chandra Reddy fenv_t oldEnv; 4475bbf4ddSJob Henandez Lara fputil::get_env(&oldEnv); 45af1315c2SSiva Chandra Reddy if (sigsetjmp(jumpBuffer, 1) == 0) 460efb376cSNick Desaulniers func->call(); 47*9426fdd4SNick Desaulniers delete func; 48af1315c2SSiva Chandra Reddy // We restore the previous floating point environment after 49af1315c2SSiva Chandra Reddy // the call to the function which can potentially raise SIGFPE. 5075bbf4ddSJob Henandez Lara fputil::set_env(&oldEnv); 51af1315c2SSiva Chandra Reddy signal(SIGFPE, oldSIGFPEHandler); 52af1315c2SSiva Chandra Reddy exceptionRaised = caughtExcept; 53af1315c2SSiva Chandra Reddy } 54af1315c2SSiva Chandra Reddy 55af1315c2SSiva Chandra Reddy } // namespace testing 565ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 57d2be9826SRoland McGrath 58d2be9826SRoland McGrath #endif // LIBC_TEST_HAS_MATCHERS() 59