/* * Test fegetexceptflag() and fesetexceptflag(). * * Prerequisites: fetestexcept(), feclearexcept() */ static void test_fegsetexceptflag(void) { fexcept_t flag; int excepts, i; assert(fetestexcept(FE_ALL_EXCEPT) == 0); for (i = 0; i < 1 << NEXCEPTS; i++) { excepts = std_except_sets[i]; assert(fegetexceptflag(&flag, excepts) == 0); raiseexcept(ALL_STD_EXCEPT); assert(fesetexceptflag(&flag, excepts) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == (ALL_STD_EXCEPT ^ excepts)); assert(fegetexceptflag(&flag, FE_ALL_EXCEPT) == 0); assert(feclearexcept(FE_ALL_EXCEPT) == 0); assert(fesetexceptflag(&flag, excepts) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == 0); assert(fesetexceptflag(&flag, ALL_STD_EXCEPT ^ excepts) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == (ALL_STD_EXCEPT ^ excepts)); assert(feclearexcept(FE_ALL_EXCEPT) == 0); } }
TEST(fenv, fegetexceptflag_fesetexceptflag) { // Set three flags. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)); ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT)); fexcept_t all; // FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW fexcept_t two; // FE_OVERFLOW | FE_UNDERFLOW ASSERT_EQ(0, fegetexceptflag(&all, FE_ALL_EXCEPT)); ASSERT_EQ(0, fegetexceptflag(&two, FE_OVERFLOW | FE_UNDERFLOW)); // Check we can restore all. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fesetexceptflag(&all, FE_ALL_EXCEPT)); ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT)); // Check that `two` only stored a subset. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fesetexceptflag(&two, FE_ALL_EXCEPT)); ASSERT_EQ(FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT)); // Check that we can restore a single flag. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fesetexceptflag(&all, FE_DIVBYZERO)); ASSERT_EQ(FE_DIVBYZERO, fetestexcept(FE_ALL_EXCEPT)); // Check that we can restore a subset of flags. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fesetexceptflag(&all, FE_OVERFLOW | FE_UNDERFLOW)); ASSERT_EQ(FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT)); }
int feraiseexcept(int e) { fexcept_t f; fegetexceptflag(&f, e); fesetexceptflag(&f, e); return 0; }
static void test_exceptionflag (void) { printf ("Test: fegetexceptionflag (FE_ALL_EXCEPT)\n"); #if FE_ALL_EXCEPT fexcept_t excepts; feclearexcept (FE_ALL_EXCEPT); feraiseexcept (FE_INVALID); fegetexceptflag (&excepts, FE_ALL_EXCEPT); feclearexcept (FE_ALL_EXCEPT); feraiseexcept (FE_OVERFLOW | FE_INEXACT); fesetexceptflag (&excepts, FE_ALL_EXCEPT); test_single_exception_fp_int (INVALID_EXC, INVALID_EXC, FE_INVALID, "INVALID (int)"); test_single_exception_fp_int (INVALID_EXC, OVERFLOW_EXC, FE_OVERFLOW, "OVERFLOW (int)"); test_single_exception_fp_int (INVALID_EXC, INEXACT_EXC, FE_INEXACT, "INEXACT (int)"); /* Same test, but using double as argument */ feclearexcept (FE_ALL_EXCEPT); feraiseexcept (FE_INVALID); fegetexceptflag (&excepts, (double)FE_ALL_EXCEPT); feclearexcept (FE_ALL_EXCEPT); feraiseexcept (FE_OVERFLOW | FE_INEXACT); fesetexceptflag (&excepts, (double)FE_ALL_EXCEPT); test_single_exception_fp_double (INVALID_EXC, INVALID_EXC, FE_INVALID, "INVALID (double)"); test_single_exception_fp_double (INVALID_EXC, OVERFLOW_EXC, FE_OVERFLOW, "OVERFLOW (double)"); test_single_exception_fp_double (INVALID_EXC, INEXACT_EXC, FE_INEXACT, "INEXACT (double)"); #endif }
/* * The feraiseexcept() function raises the supported floating-point exceptions * represented by the argument `excepts'. */ int feraiseexcept(int excepts) { excepts &= FE_ALL_EXCEPT; fesetexceptflag((fexcept_t *)&excepts, excepts); _softfloat_float_raise(excepts); return (0); }
~fpu_guard() { fesetexceptflag(&m_flags, FE_ALL_EXCEPT); }