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.
---
gcc/builtins.def | 20 +++++-----
gcc/testsuite/gcc.dg/pr80042.c | 71 ++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+), 9 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr80042.c
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 89fc74654ca..86d416f95d4 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,8 +352,8 @@ 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)
@@ -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..cc578ae67e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr80042.c
@@ -0,0 +1,71 @@
+/* dg-do run */
+/* dg-options "-O2 -lm" */
+
+#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