Improve c99 math and allow _matherr for internal functions.
git-svn-id: svn+ssh://svn.code.sf.net/p/mingw-w64/code/trunk@3076 4407c894-4637-0410-b4f5-ada5f102cad1
diff --git a/mingw-w64-crt/complex/complex_internal.h b/mingw-w64-crt/complex/complex_internal.h
index 5531430..ab4b78a 100644
--- a/mingw-w64-crt/complex/complex_internal.h
+++ b/mingw-w64-crt/complex/complex_internal.h
@@ -78,6 +78,7 @@
# define __FLT_MAXLOG 88.72283905206835F
# define __FLT_MINLOG -103.278929903431851103F
# define __FLT_LOGE2 0.693147180559945309F
+# define __FLT_REPORT(NAME) NAME "f"
#elif defined(_NEW_COMPLEX_DOUBLE)
# define __FLT_TYPE double
# define __FLT_ABI(N) N
@@ -92,6 +93,7 @@
# define __FLT_MAXLOG 7.09782712893383996843E2
# define __FLT_MINLOG -7.08396418532264106224E2
# define __FLT_LOGE2 6.93147180559945309417E-1
+# define __FLT_REPORT(NAME) NAME
#elif defined(_NEW_COMPLEX_LDOUBLE)
# define __FLT_TYPE long double
# define __FLT_ABI(N) N##l
@@ -106,6 +108,18 @@
# define __FLT_MAXLOG 1.1356523406294143949492E4L
# define __FLT_MINLOG -1.13994985314888605586758E4L
# define __FLT_LOGE2 6.9314718055994530941723E-1L
+# define __FLT_REPORT(NAME) NAME "l"
#else
# error "Unknown complex number type"
#endif
+
+#define __FLT_RPT_DOMAIN(NAME, ARG1, ARG2, RSLT) \
+ errno = EDOM, \
+ __mingw_raise_matherr (_DOMAIN, __FLT_REPORT(NAME), (double) (ARG1), \
+ (double) (ARG2), (double) (RSLT))
+#define __FLT_RPT_ERANGE(NAME, ARG1, ARG2, RSLT, OVL) \
+ errno = ERANGE, \
+ __mingw_raise_matherr (((OVL) ? _OVERFLOW : _UNDERFLOW), \
+ __FLT_REPORT(NAME), (double) (ARG1), \
+ (double) (ARG2), (double) (RSLT))
+
diff --git a/mingw-w64-crt/crt/crtexe.c b/mingw-w64-crt/crt/crtexe.c
index a89ba15..802990c 100644
--- a/mingw-w64-crt/crt/crtexe.c
+++ b/mingw-w64-crt/crt/crtexe.c
@@ -49,7 +49,6 @@
#define _commode (* __MINGW_IMP_SYMBOL(_commode))
extern int _dowildcard;
-extern int __defaultmatherr;
extern _CRTIMP void __cdecl _initterm(_PVFV *, _PVFV *);
static int __cdecl check_managed_app (void);
@@ -124,11 +123,7 @@
#endif
if (_MINGW_INSTALL_DEBUG_MATHERR)
{
- if (! __defaultmatherr)
- {
- __setusermatherr (_matherr);
- __defaultmatherr = 1;
- }
+ __setusermatherr (_matherr);
}
if (__globallocalestatus == -1)
diff --git a/mingw-w64-crt/crt/merr.c b/mingw-w64-crt/crt/merr.c
index 0f2491e..94f0a06 100644
--- a/mingw-w64-crt/crt/merr.c
+++ b/mingw-w64-crt/crt/merr.c
@@ -8,7 +8,6 @@
#include <math.h>
#include <stdio.h>
-int __defaultmatherr = 0;
typedef int (__cdecl *fUserMathErr)(struct _exception *);
static fUserMathErr stUserMathErr;
@@ -16,7 +15,7 @@
double rslt)
{
struct _exception ex;
- if (!__defaultmatherr || !stUserMathErr)
+ if (!stUserMathErr)
return;
ex.type = typ;
ex.name = name;
@@ -31,7 +30,6 @@
void __mingw_setusermatherr (int (__cdecl *f)(struct _exception *))
{
stUserMathErr = f;
- __defaultmatherr = (!f ? 0 : 1);
__setusermatherr (f);
}
diff --git a/mingw-w64-crt/math/cos.def.h b/mingw-w64-crt/math/cos.def.h
index 7a7d16b..f082f37 100644
--- a/mingw-w64-crt/math/cos.def.h
+++ b/mingw-w64-crt/math/cos.def.h
@@ -53,12 +53,12 @@
int x_class = fpclassify (x);
if (x_class == FP_NAN)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("cos", x, 0.0, x);
return x;
}
else if (x_class == FP_INFINITE)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("cos", x, 0.0, __FLT_NAN);
return __FLT_NAN;
}
return (__FLT_TYPE) __cosl_internal ((long double) x);
diff --git a/mingw-w64-crt/math/exp.def.h b/mingw-w64-crt/math/exp.def.h
index b23b091..4650fd7 100644
--- a/mingw-w64-crt/math/exp.def.h
+++ b/mingw-w64-crt/math/exp.def.h
@@ -86,13 +86,14 @@
int x_class = fpclassify (x);
if (x_class == FP_NAN)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("exp", x, 0.0, x);
return x;
}
else if (x_class == FP_INFINITE)
{
- errno = ERANGE;
- return (signbit (x) ? __FLT_CST (0.0) : __FLT_HUGE_VAL);
+ __FLT_TYPE r = (signbit (x) ? __FLT_CST (0.0) : __FLT_HUGE_VAL);
+ __FLT_RPT_ERANGE ("exp", x, 0.0, r, signbit (x));
+ return r;
}
else if (x_class == FP_ZERO)
{
@@ -100,12 +101,12 @@
}
else if (x > __FLT_MAXLOG)
{
- errno = ERANGE;
+ __FLT_RPT_ERANGE ("exp", x, 0.0, __FLT_HUGE_VAL, 1);
return __FLT_HUGE_VAL;
}
else if (x < __FLT_MINLOG)
{
- errno = ERANGE;
+ __FLT_RPT_ERANGE ("exp", x, 0.0, 0.0, 0);
return __FLT_CST(0.0);
}
else
diff --git a/mingw-w64-crt/math/expm1.def.h b/mingw-w64-crt/math/expm1.def.h
index d307809..00fa1d6 100644
--- a/mingw-w64-crt/math/expm1.def.h
+++ b/mingw-w64-crt/math/expm1.def.h
@@ -51,7 +51,7 @@
int x_class = fpclassify (x);
if (x_class == FP_NAN)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("expm1", x, 0.0, x);
return x;
}
else if (x_class == FP_INFINITE)
diff --git a/mingw-w64-crt/math/log.def.h b/mingw-w64-crt/math/log.def.h
index 5a03c4e..9eddcb8 100644
--- a/mingw-w64-crt/math/log.def.h
+++ b/mingw-w64-crt/math/log.def.h
@@ -53,12 +53,12 @@
int x_class = fpclassify (x);
if (signbit (x))
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("log", x, 0.0, __FLT_NAN);
return __FLT_NAN;
}
else if (x_class == FP_ZERO)
{
- errno = ERANGE;
+ __FLT_RPT_ERANGE ("log", x, 0.0, -__FLT_HUGE_VAL, 1);
return -__FLT_HUGE_VAL;
}
else if (x_class == FP_INFINITE)
diff --git a/mingw-w64-crt/math/pow.def.h b/mingw-w64-crt/math/pow.def.h
index d9f7d1e..8a08508 100644
--- a/mingw-w64-crt/math/pow.def.h
+++ b/mingw-w64-crt/math/pow.def.h
@@ -81,8 +81,9 @@
return __FLT_CST(1.0);
else if (x_class == FP_NAN || y_class == FP_NAN)
{
- errno = EDOM;
- return (signbit(x) ? -__FLT_NAN : __FLT_NAN);
+ rslt = (signbit(x) ? -__FLT_NAN : __FLT_NAN);
+ __FLT_RPT_DOMAIN ("pow", x, y, rslt);
+ return rslt;
}
else if (x_class == FP_ZERO)
{
@@ -91,7 +92,7 @@
if (signbit(x) && __FLT_ABI(modf) (y, &d) != 0.0)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("pow", x, y, -__FLT_NAN);
return -__FLT_NAN;
}
odd_y = (__FLT_ABI (modf) (__FLT_ABI (ldexp) (y, -1), &d) != 0.0) ? 1 : 0;
@@ -124,7 +125,7 @@
/* pow (x, y) signals the invalid operation exception for finite x < 0 and finite non-integer y. */
if (signbit(x) && __FLT_ABI(modf) (y, &d) != 0.0)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("pow", x, y, -__FLT_NAN);
return -__FLT_NAN;
}
odd_y = (__FLT_ABI (modf) (__FLT_ABI (ldexp) (y, -1), &d) != 0.0) ? 1 : 0;
@@ -150,7 +151,7 @@
if (signbit (x) && (__FLT_TYPE) __FLT_ABI(modf) (y, &d) != 0.0)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("pow", x, y, -__FLT_NAN);
return -__FLT_NAN;
}
/* As exp already checks for minlog and maxlog no further checks are necessary. */
diff --git a/mingw-w64-crt/math/sin.def.h b/mingw-w64-crt/math/sin.def.h
index 473f954..1673b34 100644
--- a/mingw-w64-crt/math/sin.def.h
+++ b/mingw-w64-crt/math/sin.def.h
@@ -53,12 +53,12 @@
int x_class = fpclassify (x);
if (x_class == FP_NAN)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("sin", x, 0.0, x);
return x;
}
else if (x_class == FP_INFINITE)
{
- errno = EDOM;
+ __FLT_RPT_DOMAIN ("sin", x, 0.0, __FLT_NAN);
return __FLT_NAN;
}
return (__FLT_TYPE) __sinl_internal ((long double) x);
diff --git a/mingw-w64-crt/math/sqrt.def.h b/mingw-w64-crt/math/sqrt.def.h
index 9002bc0..af349bc 100644
--- a/mingw-w64-crt/math/sqrt.def.h
+++ b/mingw-w64-crt/math/sqrt.def.h
@@ -52,8 +52,9 @@
int x_class = fpclassify (x);
if (x_class == FP_NAN || signbit (x))
{
- errno = EDOM;
- return (signbit (x) ? -__FLT_NAN : __FLT_NAN);
+ res = (signbit (x) ? -__FLT_NAN : __FLT_NAN);
+ __FLT_RPT_DOMAIN ("sqrt", x, 0.0, res);
+ return res;
}
else if (x_class == FP_ZERO)
return __FLT_CST (0.0);