int fedisableexcept (int excepts) { fenv_union_t fe; int result; result = fegetexcept (); if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; fe.fenv = fegetenv_register (); if (excepts & FE_INEXACT) fe.l[1] &= ~(1 << (31 - FPSCR_XE)); if (excepts & FE_DIVBYZERO) fe.l[1] &= ~(1 << (31 - FPSCR_ZE)); if (excepts & FE_UNDERFLOW) fe.l[1] &= ~(1 << (31 - FPSCR_UE)); if (excepts & FE_OVERFLOW) fe.l[1] &= ~(1 << (31 - FPSCR_OE)); if (excepts & FE_INVALID) fe.l[1] &= ~(1 << (31 - FPSCR_VE)); fesetenv_register (fe.fenv); if ((fegetexcept () & excepts) != 0) result = -1; return result; }
static int do_test (void) { if (FE_ALL_EXCEPT == 0) { printf("Skipping test; no support for FP exceptions.\n"); return 0; } int except_mask = 0; #ifdef FE_DIVBYZERO except_mask |= FE_DIVBYZERO; #endif #ifdef FE_INVALID except_mask |= FE_INVALID; #endif #ifdef FE_OVERFLOW except_mask |= FE_OVERFLOW; #endif #ifdef FE_UNDERFLOW except_mask |= FE_UNDERFLOW; #endif int status = feenableexcept (except_mask); except_mask = fegetexcept (); if (except_mask == -1) { printf("\nBefore getcontext(): fegetexcept returned: %d\n", except_mask); return 1; } ucontext_t ctx; status = getcontext(&ctx); if (status) { printf("\ngetcontext failed, errno: %d.\n", errno); return 1; } printf ("\nDone with getcontext()!\n"); fflush (NULL); int mask = fegetexcept (); if (mask != except_mask) { printf("\nAfter getcontext(): fegetexcept returned: %d, expected: %d.\n", mask, except_mask); return 1; } printf("\nAt end fegetexcept() returned %d, expected: %d.\n", mask, except_mask); return 0; }
static void test_feupdateenv (void) { #if defined FE_NOMASK_ENV && defined FE_ALL_EXCEPT int res; fedisableexcept (FE_ALL_EXCEPT); res = feupdateenv (FE_NOMASK_ENV); if (!EXCEPTION_ENABLE_SUPPORTED (FE_ALL_EXCEPT) && (res != 0)) { puts ("feupdateenv (FE_NOMASK_ENV)) not supported, cannot test."); return; } else if (res != 0) { puts ("feupdateenv (FE_NOMASK_ENV) failed"); count_errors++; } if (fegetexcept () != FE_ALL_EXCEPT) { puts ("feupdateenv did not set all exceptions"); count_errors++; } #endif }
int main (int argc, char **argv) { double s; struct sigaction act; act.sa_sigaction = (void(*))fhdl; sigemptyset (&act.sa_mask); act.sa_flags = SA_SIGINFO; // printf ("Old divByZero exception: 0x%08X\n", feenableexcept (FE_DIVBYZERO)); printf ("Old invalid exception: 0x%08X\n", feenableexcept (FE_INVALID)); printf ("New fp exception: 0x%08X\n", fegetexcept ()); // set handler if (sigaction(SIGFPE, &act, (struct sigaction *)0) != 0) { perror("Yikes"); exit(-1); } // s = 1.0 / 0.0; // FE_DIVBYZERO s = 0.0 / 0.0; // FE_INVALID return 0; }
int fpe_get_traps () { #ifdef FPE_WITH_TRAP_CONTROL return fegetexcept (); #else return -1; #endif }
TEST(fenv, feenableexcept_fegetexcept) { #if defined(__aarch64__) || defined(__arm__) // ARM doesn't support this. They used to if you go back far enough, but it was removed in // the Cortex-A8 between r3p1 and r3p2. ASSERT_EQ(-1, feenableexcept(FE_INVALID)); ASSERT_EQ(0, fegetexcept()); ASSERT_EQ(-1, feenableexcept(FE_DIVBYZERO)); ASSERT_EQ(0, fegetexcept()); ASSERT_EQ(-1, feenableexcept(FE_OVERFLOW)); ASSERT_EQ(0, fegetexcept()); ASSERT_EQ(-1, feenableexcept(FE_UNDERFLOW)); ASSERT_EQ(0, fegetexcept()); ASSERT_EQ(-1, feenableexcept(FE_INEXACT)); ASSERT_EQ(0, fegetexcept()); ASSERT_EQ(-1, feenableexcept(FE_DENORMAL)); ASSERT_EQ(0, fegetexcept()); #else // We can't recover from SIGFPE, so sacrifice a child... pid_t pid = fork(); ASSERT_NE(-1, pid) << strerror(errno); if (pid == 0) { feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT)); ASSERT_EQ(0, feenableexcept(FE_INVALID)); ASSERT_EQ(FE_INVALID, fegetexcept()); ASSERT_EQ(0, feraiseexcept(FE_INVALID)); _exit(123); } AssertChildExited(pid, -SIGFPE); #endif }
TEST(fenv, fedisableexcept_fegetexcept) { feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT)); // No SIGFPE please... ASSERT_EQ(0, fedisableexcept(FE_ALL_EXCEPT)); ASSERT_EQ(0, fegetexcept()); ASSERT_EQ(0, feraiseexcept(FE_INVALID)); ASSERT_EQ(FE_INVALID, fetestexcept(FE_ALL_EXCEPT)); }
void restoreFPExceptions(bool oldState) { bool currentState; #if defined(WIN32) uint32_t cw = _controlfp(0, 0); currentState = ~cw & (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW); #elif defined(__OSX__) #if !defined(MTS_SSE) #warning SSE must be enabled to handle FP exceptions on OSX #else currentState = query_fpexcept_sse() != 0; #endif #else currentState = fegetexcept() & (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); #endif if (oldState != currentState) { if (oldState) enableFPExceptions(); else disableFPExceptions(); } }
bool disableFPExceptions() { bool exceptionsWereEnabled = false; #if defined(WIN32) _clearfp(); uint32_t cw = _controlfp(0, 0); exceptionsWereEnabled = ~cw & (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW); cw |= _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW; _controlfp(cw, _MCW_EM); #elif defined(__OSX__) #if !defined(MTS_SSE) #warning SSE must be enabled to handle FP exceptions on OSX #else exceptionsWereEnabled = query_fpexcept_sse() != 0; #endif #else exceptionsWereEnabled = fegetexcept() & (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); fedisableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); #endif #if defined(MTS_SSE) disable_fpexcept_sse(); #endif return exceptionsWereEnabled; }
/* * Test fegetexcept(), fedisableexcept(), and feenableexcept(). * * Prerequisites: fetestexcept(), feraiseexcept() */ static void test_masking(void) { struct sigaction act; int except, i, pass, raise, status; assert((fegetexcept() & ALL_STD_EXCEPT) == 0); assert((feenableexcept(FE_INVALID|FE_OVERFLOW) & ALL_STD_EXCEPT) == 0); assert((feenableexcept(FE_UNDERFLOW) & ALL_STD_EXCEPT) == (FE_INVALID | FE_OVERFLOW)); assert((fedisableexcept(FE_OVERFLOW) & ALL_STD_EXCEPT) == (FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)); assert((fegetexcept() & ALL_STD_EXCEPT) == (FE_INVALID | FE_UNDERFLOW)); assert((fedisableexcept(FE_ALL_EXCEPT) & ALL_STD_EXCEPT) == (FE_INVALID | FE_UNDERFLOW)); assert((fegetexcept() & ALL_STD_EXCEPT) == 0); sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = trap_handler; for (pass = 0; pass < 2; pass++) { for (i = 0; i < NEXCEPTS; i++) { except = std_excepts[i]; /* over/underflow may also raise inexact */ if (except == FE_INEXACT) raise = FE_DIVBYZERO | FE_INVALID; else raise = ALL_STD_EXCEPT ^ except; /* * We need to fork a child process because * there isn't a portable way to recover from * a floating-point exception. */ switch(fork()) { case 0: /* child */ assert((fegetexcept() & ALL_STD_EXCEPT) == 0); assert((feenableexcept(except) & ALL_STD_EXCEPT) == 0); assert(fegetexcept() == except); raiseexcept(raise); assert(feraiseexcept(raise) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == raise); assert(sigaction(SIGFPE, &act, NULL) == 0); switch (pass) { case 0: raiseexcept(except); case 1: feraiseexcept(except); default: assert(0); } assert(0); default: /* parent */ assert(wait(&status) > 0); /* * Avoid assert() here so that it's possible * to examine a failed child's core dump. */ if (!WIFEXITED(status)) errx(1, "child aborted\n"); assert(WEXITSTATUS(status) == 0); break; case -1: /* error */ assert(0); } } } assert(fetestexcept(FE_ALL_EXCEPT) == 0); }
void fegetexcept_(int * val){ *val=fegetexcept(); }
/* Tests for feenableexcept/fedisableexcept/fegetexcept. */ static void feenable_test (const char *flag_name, int fe_exc) { int excepts; printf ("Tests for feenableexcepts etc. with flag %s\n", flag_name); /* First disable all exceptions. */ if (fedisableexcept (FE_ALL_EXCEPT) == -1) { printf ("Test: fedisableexcept (FE_ALL_EXCEPT) failed\n"); ++count_errors; /* If this fails, the other tests don't make sense. */ return; } excepts = fegetexcept (); if (excepts != 0) { printf ("Test: fegetexcept (%s) failed, return should be 0, is %d\n", flag_name, excepts); ++count_errors; } excepts = feenableexcept (fe_exc); if (!EXCEPTION_ENABLE_SUPPORTED (fe_exc) && excepts == -1) { printf ("Test: not testing feenableexcept, it isn't implemented.\n"); return; } if (excepts == -1) { printf ("Test: feenableexcept (%s) failed\n", flag_name); ++count_errors; return; } if (excepts != 0) { printf ("Test: feenableexcept (%s) failed, return should be 0, is %x\n", flag_name, excepts); ++count_errors; } excepts = fegetexcept (); if (excepts != fe_exc) { printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n", flag_name, fe_exc, excepts); ++count_errors; } /* And now disable the exception again. */ excepts = fedisableexcept (fe_exc); if (excepts == -1) { printf ("Test: fedisableexcept (%s) failed\n", flag_name); ++count_errors; return; } if (excepts != fe_exc) { printf ("Test: fedisableexcept (%s) failed, return should be 0x%x, is 0x%x\n", flag_name, fe_exc, excepts); ++count_errors; } excepts = fegetexcept (); if (excepts != 0) { printf ("Test: fegetexcept (%s) failed, return should be 0, is 0x%x\n", flag_name, excepts); ++count_errors; } /* Now the other way round: Enable all exceptions and disable just this one. */ if (feenableexcept (FE_ALL_EXCEPT) == -1) { printf ("Test: feenableexcept (FE_ALL_EXCEPT) failed\n"); ++count_errors; /* If this fails, the other tests don't make sense. */ return; } excepts = fegetexcept (); if (excepts != FE_ALL_EXCEPT) { printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n", flag_name, FE_ALL_EXCEPT, excepts); ++count_errors; } excepts = fedisableexcept (fe_exc); if (excepts == -1) { printf ("Test: fedisableexcept (%s) failed\n", flag_name); ++count_errors; return; } if (excepts != FE_ALL_EXCEPT) { printf ("Test: fedisableexcept (%s) failed, return should be 0, is 0x%x\n", flag_name, excepts); ++count_errors; } excepts = fegetexcept (); if (excepts != (FE_ALL_EXCEPT & ~fe_exc)) { printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n", flag_name, (FE_ALL_EXCEPT & ~fe_exc), excepts); ++count_errors; } /* And now enable the exception again. */ excepts = feenableexcept (fe_exc); if (excepts == -1) { printf ("Test: feenableexcept (%s) failed\n", flag_name); ++count_errors; return; } if (excepts != (FE_ALL_EXCEPT & ~fe_exc)) { printf ("Test: feenableexcept (%s) failed, return should be 0, is 0x%x\n", flag_name, excepts); ++count_errors; } excepts = fegetexcept (); if (excepts != FE_ALL_EXCEPT) { printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n", flag_name, FE_ALL_EXCEPT, excepts); ++count_errors; } feexcp_nomask_test (flag_name, fe_exc); feexcp_mask_test (flag_name, fe_exc); }
unsigned int fpe_get_trapped() { return (unsigned int)fegetexcept(); }
static int do_test (void) { if (FE_ALL_EXCEPT == 0) { printf("Skipping test; no support for FP exceptions.\n"); return 0; } int except_mask = 0; #ifdef FE_DIVBYZERO except_mask |= FE_DIVBYZERO; #endif #ifdef FE_INVALID except_mask |= FE_INVALID; #endif #ifdef FE_OVERFLOW except_mask |= FE_OVERFLOW; #endif #ifdef FE_UNDERFLOW except_mask |= FE_UNDERFLOW; #endif int status = feenableexcept (except_mask); except_mask = fegetexcept (); if (except_mask == -1) { printf("\nBefore getcontext(): fegetexcept returned: %d\n", except_mask); return 1; } ucontext_t ctx; status = getcontext(&ctx); if (status) { printf("\ngetcontext failed, errno: %d.\n", errno); return 1; } printf ("\nDone with getcontext()!\n"); fflush (NULL); /* On nios2 and tilepro, GCC 5 warns that except_mask may be used uninitialized. Because it is always initialized and nothing in this test ever calls setcontext (a setcontext call could result in local variables being clobbered on the second return from getcontext), in fact an uninitialized use is not possible. */ DIAG_PUSH_NEEDS_COMMENT; DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); int mask = fegetexcept (); if (mask != except_mask) { printf("\nAfter getcontext(): fegetexcept returned: %d, expected: %d.\n", mask, except_mask); return 1; } printf("\nAt end fegetexcept() returned %d, expected: %d.\n", mask, except_mask); DIAG_POP_NEEDS_COMMENT; return 0; }