POSIX says that sin and cos should set errno to EDOM when infinity is passed to them. Make sure this is accounted for in builtins.def, and add tests.
gcc/ PR middle-end/80042 * builtins.def: (sin|cos)(f|l) can set errno. gcc/testsuite/ * gcc.dg/pr80042.c: New testcase. --- V2: Add { } to all dg directives Fix cosl too (the test was failing on this and caught it) Add -fmath-errno just in case (apparently Darwin might have problems without it) $ make -k check-gcc-c RUNTESTFLAGS="dg.exp=pr80042.c" shows: # of expected passes 2 so I think the tests are passing as expected. gcc/builtins.def | 22 ++++++----- gcc/testsuite/gcc.dg/pr80042.c | 71 ++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr80042.c diff --git a/gcc/builtins.def b/gcc/builtins.def index 89fc74654ca..c7d2987a9c4 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -288,6 +288,8 @@ along with GCC; see the file COPYING3. If not see maintenance purposes. */ #undef ATTR_MATHFN_FPROUNDING_STORE #define ATTR_MATHFN_FPROUNDING_STORE ATTR_NOTHROW_LEAF_LIST +#undef ATTR_MATHFN_FPROUNDING_ERRNO_STORE +#define ATTR_MATHFN_FPROUNDING_ERRNO_STORE ATTR_NOTHROW_LEAF_LIST /* Define an attribute list for leaf functions that do not throw exceptions normally, but may throw exceptions when using @@ -350,14 +352,14 @@ DEF_C99_BUILTIN (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDO #define COPYSIGN_TYPE(F) BT_FN_##F##_##F##_##F DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_COPYSIGN, "copysign", COPYSIGN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) #undef COPYSIGN_TYPE -DEF_LIB_BUILTIN (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) -DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_LIB_BUILTIN (BUILT_IN_COSH, "cosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHF, "coshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHL, "coshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) #define COSH_TYPE(F) BT_FN_##F##_##F DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_COSH, "cosh", COSH_TYPE, ATTR_MATHFN_FPROUNDING_ERRNO) -DEF_C99_C90RES_BUILTIN (BUILT_IN_COSL, "cosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_COSL, "cosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_COS, "cos", COSH_TYPE, ATTR_MATHFN_FPROUNDING) DEF_EXT_LIB_BUILTIN (BUILT_IN_DREM, "drem", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN (BUILT_IN_DREMF, "dremf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) @@ -674,18 +676,18 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD128, "signbitd128", BT_FN_INT_DFLOAT128 DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICAND, "significand", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDF, "significandf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDL, "significandl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) -DEF_LIB_BUILTIN (BUILT_IN_SIN, "sin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) -DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOS, "sincos", BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE) -DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSF, "sincosf", BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE) -DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSL, "sincosl", BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE) -DEF_C99_C90RES_BUILTIN (BUILT_IN_SINF, "sinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_SIN, "sin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOS, "sincos", BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_ERRNO_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSF, "sincosf", BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR, ATTR_MATHFN_FPROUNDING_ERRNO_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSL, "sincosl", BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_ERRNO_STORE) +DEF_C99_C90RES_BUILTIN (BUILT_IN_SINF, "sinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_LIB_BUILTIN (BUILT_IN_SINH, "sinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHF, "sinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHL, "sinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) #define SINH_TYPE(F) BT_FN_##F##_##F DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_SINH, "sinh", SINH_TYPE, ATTR_MATHFN_FPROUNDING_ERRNO) -DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "sinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) -DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_SIN, "sin", SINH_TYPE, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "sinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_SIN, "sin", SINH_TYPE, ATTR_MATHFN_FPROUNDING_ERRNO) #undef SINH_TYPE DEF_LIB_BUILTIN (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) diff --git a/gcc/testsuite/gcc.dg/pr80042.c b/gcc/testsuite/gcc.dg/pr80042.c new file mode 100644 index 00000000000..bd1e490360b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr80042.c @@ -0,0 +1,71 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -lm -fmath-errno" } */ + +#include <errno.h> + +void test_double(void) +{ + double s, c; + + errno = 0; + s = __builtin_sin(__builtin_inf()); + if (errno != EDOM) + __builtin_abort(); + + errno = 0; + c = __builtin_cos(__builtin_inf()); + if (errno != EDOM) + __builtin_abort(); + + errno = 0; + __builtin_sincos(__builtin_inf(), &s, &c); + if (errno != EDOM) + __builtin_abort(); +} + +void test_float(void) +{ + float s, c; + + errno = 0; + s = __builtin_sinf(__builtin_inff()); + if (errno != EDOM) + __builtin_abort(); + + errno = 0; + c = __builtin_cosf(__builtin_inff()); + if (errno != EDOM) + __builtin_abort(); + + errno = 0; + __builtin_sincosf(__builtin_inff(), &s, &c); + if (errno != EDOM) + __builtin_abort(); +} + +void test_longdouble(void) +{ + long double s, c; + + errno = 0; + s = __builtin_sinl(__builtin_infl()); + if (errno != EDOM) + __builtin_abort(); + + errno = 0; + c = __builtin_cosl(__builtin_infl()); + if (errno != EDOM) + __builtin_abort(); + + errno = 0; + __builtin_sincosl(__builtin_infl(), &s, &c); + if (errno != EDOM) + __builtin_abort(); +} + +int main(void) +{ + test_double(); + test_float(); + test_longdouble(); +} -- 2.39.5