File 1103-Make-sure-that-math-acos-asin-1-consistently-fail-fo.patch of Package erlang

From 434abe68d817ed48be87accf214e0de1e1f777a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Mon, 25 Jan 2021 10:30:59 +0100
Subject: [PATCH] Make sure that math:{acos,asin}/1 consistently fail for
 domain errors

We require a C compiler that supports C99, but on Solaris it could
happen that even though the C compiler (gcc) supports C99, the runtime
libraries could still behave as a previous version (X/Open or C90).

Specifically, the acos() and asin() function in C90 return 0.0 on a
domain error, but sets the errno to EDOM. To ensure that we raise an
exception, we will need to check errno after calling the those
functions.

While at it, also provide extended BIF information for `math:acosh/1`
and `math:atanh/1`.
---
 erts/aclocal.m4                      | 22 -----------------
 erts/configure.in                    |  1 -
 erts/emulator/beam/erl_math.c        | 36 ++++++++++++++++++++++++++--
 lib/stdlib/src/erl_stdlib_errors.erl |  4 ++++
 lib/stdlib/test/math_SUITE.erl       |  6 +++++
 5 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index a6df75233f..e40e2f1a22 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -474,28 +474,6 @@ case ${ac_cv_struct_sockaddr_sa_len} in
 esac
 ])
 
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_STRUCT_EXCEPTION
-dnl
-dnl Check to see whether the system supports the matherr function
-dnl and its associated type "struct exception".
-dnl
-
-AC_DEFUN(LM_STRUCT_EXCEPTION,
-[AC_CACHE_CHECK([for struct exception (and matherr function)],
- ac_cv_struct_exception,
-AC_TRY_COMPILE([#include <math.h>],
-  [struct exception x; x.type = DOMAIN; x.type = SING;],
-  ac_cv_struct_exception=yes, ac_cv_struct_exception=no))
-
-case "${ac_cv_struct_exception}" in
-  "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;;
-  *  ) ;;
-esac
-])
-
-
 dnl ----------------------------------------------------------------------
 dnl
 dnl LM_SYS_IPV6
diff --git a/erts/configure.in b/erts/configure.in
index 70dceabcfe..76cccea206 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1870,7 +1870,6 @@ AC_TYPE_SIZE_T
 
 AC_STRUCT_TM
 LM_STRUCT_SOCKADDR_SA_LEN
-LM_STRUCT_EXCEPTION
 
 AC_CHECK_SIZEOF(char, 1)
 AC_CHECK_SIZEOF(short)
diff --git a/erts/emulator/beam/erl_math.c b/erts/emulator/beam/erl_math.c
index 1f270eb55f..9b93c9fca3 100644
--- a/erts/emulator/beam/erl_math.c
+++ b/erts/emulator/beam/erl_math.c
@@ -60,6 +60,38 @@ math_call_1(Process* p, double (*func)(double), Eterm arg1)
     return res;
 }
 
+/*
+ * Execute a math function and also test errno for errors.
+ * Called for math:acos/1 and math:asin/1.
+ */
+static Eterm
+math_call_errno_1(Process* p, double (*func)(double), Eterm arg1)
+{
+    Eterm res;
+
+    errno = 0;
+    res = math_call_1(p, func, arg1);
+
+    /*
+     * We require a C compiler that supports C99, but on Solaris
+     * it could happen that even though the C compiler (gcc) supports
+     * C99, the runtime libraries could still behave as a previous
+     * version (X/Open or C90).
+     *
+     * Specifically, the acos() and asin() function in C90 return 0.0
+     * on a domain error, but sets the errno to EDOM. To ensure that
+     * we raise an exception, we will need to check errno. (Testing
+     * errno for all math functions would be wrong, because when pow()
+     * underflows, 0.0 is returned but errno is set to ERANGE on
+     * Solaris. Undeflow is not considered an error for the functions
+     * in the math module.)
+     */
+    if (is_value(res) && errno != 0) {
+        p->freason = BADARITH;
+        return THE_NON_VALUE;
+    }
+    return res;
+}
 
 static Eterm
 math_call_2(Process* p, double (*func)(double, double), Eterm arg1, Eterm arg2)
@@ -140,7 +172,7 @@ BIF_RETTYPE math_tanh_1(BIF_ALIST_1)
 
 BIF_RETTYPE math_acos_1(BIF_ALIST_1)
 {
-    return math_call_1(BIF_P, acos, BIF_ARG_1);
+    return math_call_errno_1(BIF_P, acos, BIF_ARG_1);
 }
 
 BIF_RETTYPE math_acosh_1(BIF_ALIST_1)
@@ -154,7 +186,7 @@ BIF_RETTYPE math_acosh_1(BIF_ALIST_1)
 
 BIF_RETTYPE math_asin_1(BIF_ALIST_1)
 {
-    return math_call_1(BIF_P, asin, BIF_ARG_1);
+    return math_call_errno_1(BIF_P, asin, BIF_ARG_1);
 }
 
 BIF_RETTYPE math_asinh_1(BIF_ALIST_1)
-- 
2.26.2

openSUSE Build Service is sponsored by