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

Reply via email to