1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
/* { dg-do run } */
/* { dg-require-effective-target fenv_exceptions } */
/* { dg-options "-lm -fno-builtin" } */
/* This testcase ensures that the builtins are correctly expanded and match the
expected result.
"-fno-builtin" option is used to enable calls to libc implementation of the
gcc builtins tested when not using __builtin_ prefix.
The excepts parameter needs to be passed as constant to
__builtin_feclearexcept and __builtin_feraiseexcept because some bultins only
expand on constant input. */
#include <fenv.h>
#ifdef DEBUG
#include <stdio.h>
#define INFO(...) printf(__VA_ARGS__)
#define FAIL(ret, raised, expected, excepts, excepts_str, func) \
printf("ERROR [l %d] testing %s (%x): %s returned %d." \
" Raised except bits %x, expecected %x\n", \
__LINE__, excepts_str, excepts, func, ret, raised, expected)
#else
void abort (void);
#define INFO(...)
#define FAIL(ret, raised, expected, excepts, excepts_str, func) abort()
#endif
#define TEST(excepts) \
do { \
int ret = 0; \
int raised = 0; \
\
INFO("test: %s (%x)\n", #excepts, excepts); \
\
feclearexcept(FE_ALL_EXCEPT); \
ret = __builtin_feraiseexcept(excepts); \
raised = fetestexcept(FE_ALL_EXCEPT); \
if (ret != 0 || raised != (excepts)) \
FAIL(ret, raised, excepts, excepts, #excepts, \
"__builtin_feraiseexcept"); \
\
feraiseexcept(FE_ALL_EXCEPT); \
ret = __builtin_feclearexcept(excepts); \
raised = fetestexcept(FE_ALL_EXCEPT); \
if (ret != 0 || raised != (FE_ALL_EXCEPT & ~(excepts))) \
FAIL(ret, raised, FE_ALL_EXCEPT & ~(excepts), excepts, #excepts, \
"__builtin_feclearexcept"); \
} while (0)
int
main ()
{
TEST(0);
TEST(FE_ALL_EXCEPT);
TEST(FE_INVALID);
TEST(FE_DIVBYZERO);
TEST(FE_INEXACT);
TEST(FE_OVERFLOW);
TEST(FE_UNDERFLOW);
TEST(FE_INVALID | FE_DIVBYZERO);
TEST(FE_INVALID | FE_INEXACT);
TEST(FE_INVALID | FE_OVERFLOW);
TEST(FE_INVALID | FE_UNDERFLOW);
TEST(FE_DIVBYZERO | FE_INEXACT);
TEST(FE_DIVBYZERO | FE_OVERFLOW);
TEST(FE_DIVBYZERO | FE_UNDERFLOW);
TEST(FE_INEXACT | FE_OVERFLOW);
TEST(FE_INEXACT | FE_UNDERFLOW);
TEST(FE_OVERFLOW | FE_UNDERFLOW);
TEST(FE_INVALID | FE_DIVBYZERO | FE_INEXACT);
TEST(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
TEST(FE_INVALID | FE_DIVBYZERO | FE_UNDERFLOW);
TEST(FE_INVALID | FE_INEXACT | FE_OVERFLOW);
TEST(FE_INVALID | FE_INEXACT | FE_UNDERFLOW);
TEST(FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW);
TEST(FE_DIVBYZERO | FE_INEXACT | FE_OVERFLOW);
TEST(FE_DIVBYZERO | FE_INEXACT | FE_UNDERFLOW);
TEST(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);
TEST(FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW);
TEST(FE_INVALID | FE_DIVBYZERO | FE_INEXACT | FE_UNDERFLOW);
TEST(FE_INVALID | FE_DIVBYZERO | FE_INEXACT | FE_OVERFLOW);
TEST(FE_INVALID | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW);
TEST(FE_INVALID | FE_INEXACT | FE_UNDERFLOW | FE_OVERFLOW);
TEST(FE_DIVBYZERO | FE_INEXACT | FE_UNDERFLOW | FE_OVERFLOW);
return 0;
}
|