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