crt: Fix return value of fegetexcept(), fedisableexcept() and feenableexcept() functions Function __mingw_controlfp() returns bits for disabled exceptions, but function fegetexcept() must return bits for enabled exceptions. So negate bits for return value. Function __mingw_controlfp() when modifying cw returns new state, but functions fedisableexcept() and feenableexcept() must return old state. So before modifying cw via __mingw_controlfp(), call fegetexcept() to calculate return value of both fedisableexcept() and feenableexcept() functions. Also checks for input argument and return -1 when is invalid. Signed-off-by: LIU Hao <lh_mouse@126.com>
diff --git a/mingw-w64-crt/misc/fedisableexcept.c b/mingw-w64-crt/misc/fedisableexcept.c index 29b905e..5c3328d 100644 --- a/mingw-w64-crt/misc/fedisableexcept.c +++ b/mingw-w64-crt/misc/fedisableexcept.c
@@ -4,5 +4,8 @@ int __cdecl fedisableexcept(int excepts) { - return __mingw_controlfp(excepts & FE_ALL_EXCEPT, excepts & FE_ALL_EXCEPT) & FE_ALL_EXCEPT; + if (excepts & ~FE_ALL_EXCEPT) return -1; + int old_excepts = fegetexcept(); + __mingw_controlfp(excepts, excepts); + return old_excepts; }
diff --git a/mingw-w64-crt/misc/feenableexcept.c b/mingw-w64-crt/misc/feenableexcept.c index 8a40bd5..7bd6f75 100644 --- a/mingw-w64-crt/misc/feenableexcept.c +++ b/mingw-w64-crt/misc/feenableexcept.c
@@ -4,5 +4,8 @@ int __cdecl feenableexcept(int excepts) { - return __mingw_controlfp(0, excepts & FE_ALL_EXCEPT) & FE_ALL_EXCEPT; + if (excepts & ~FE_ALL_EXCEPT) return -1; + int old_excepts = fegetexcept(); + __mingw_controlfp(0, excepts); + return old_excepts; }
diff --git a/mingw-w64-crt/misc/fegetexcept.c b/mingw-w64-crt/misc/fegetexcept.c index ced9f50..6bbf8d1 100644 --- a/mingw-w64-crt/misc/fegetexcept.c +++ b/mingw-w64-crt/misc/fegetexcept.c
@@ -4,5 +4,5 @@ int __cdecl fegetexcept(void) { - return __mingw_controlfp(0, 0) & FE_ALL_EXCEPT; + return ~__mingw_controlfp(0, 0) & FE_ALL_EXCEPT; }