Piotr Caban : msvcrt: Fix _control87 ambiguous return value.

Alexandre Julliard julliard at winehq.org
Tue Jul 7 15:47:07 CDT 2020


Module: wine
Branch: master
Commit: 33190b694f09a2b4d1ffb4d4a995ada64c7c2a10
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=33190b694f09a2b4d1ffb4d4a995ada64c7c2a10

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Tue Jul  7 16:08:00 2020 +0200

msvcrt: Fix _control87 ambiguous return value.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/math.c         |  1 +
 dlls/ucrtbase/tests/misc.c | 28 ++++++++++++++++++++++++++++
 include/msvcrt/float.h     |  3 +++
 3 files changed, 32 insertions(+)

diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index 5a4126ad58..2e9154795d 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -1250,6 +1250,7 @@ unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
     __control87_2( newval, mask, &flags, &sse2_cw );
 
     if ((flags ^ sse2_cw) & (MSVCRT__MCW_EM | MSVCRT__MCW_RC)) flags |= MSVCRT__EM_AMBIGUOUS;
+    flags |= sse2_cw;
 #elif defined(__x86_64__)
     unsigned long fpword;
     unsigned int old_flags;
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index eb0c79be2b..cd100cf1a9 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -335,6 +335,33 @@ static void test___fpe_flt_rounds(void)
     ok((_controlfp(_RC_CHOP, _RC_CHOP) & _RC_CHOP) == _RC_CHOP, "_controlfp(_RC_CHOP, _RC_CHOP) failed\n");
     ret = __fpe_flt_rounds();
     ok(ret == 0, "__fpe_flt_rounds returned %d\n", ret);
+
+    _controlfp(cfp, _MCW_EM | _MCW_RC | _MCW_PC);
+}
+
+static void test__control87_2(void)
+{
+#ifdef __i386__
+    unsigned int x86_cw_init, sse2_cw_init, x86_cw, sse2_cw, r;
+
+    r = __control87_2(0, 0, &x86_cw_init, &sse2_cw_init);
+    ok(r == 1, "__control87_2 returned %d\n", r);
+
+    r = __control87_2(0, _EM_INVALID, &x86_cw, NULL);
+    ok(r == 1, "__control87_2 returned %d\n", r);
+    ok(x86_cw == (x86_cw_init & ~_EM_INVALID), "x86_cw = %x, x86_cw_init = %x\n", x86_cw, x86_cw_init);
+
+    r = __control87_2(0, 0, &x86_cw, &sse2_cw);
+    ok(r == 1, "__control87_2 returned %d\n", r);
+    ok(x86_cw == (x86_cw_init & ~_EM_INVALID), "x86_cw = %x, x86_cw_init = %x\n", x86_cw, x86_cw_init);
+    ok(sse2_cw == sse2_cw_init, "sse2_cw = %x, sse2_cw_init = %x\n", sse2_cw, sse2_cw_init);
+
+    r = _control87(0, 0);
+    ok(r == (x86_cw | sse2_cw | _EM_AMBIGUOUS), "r = %x, expected %x\n",
+            r, x86_cw | sse2_cw | _EM_AMBIGUOUS);
+
+    _control87(x86_cw_init, ~0);
+#endif
 }
 
 static void __cdecl global_invalid_parameter_handler(
@@ -1347,6 +1374,7 @@ START_TEST(misc)
     test__register_onexit_function();
     test__execute_onexit_table();
     test___fpe_flt_rounds();
+    test__control87_2();
     test__get_narrow_winmain_command_line(arg_v[0]);
     test__sopen_dispatch();
     test__sopen_s();
diff --git a/include/msvcrt/float.h b/include/msvcrt/float.h
index 06eadec0ff..0e0ca34219 100644
--- a/include/msvcrt/float.h
+++ b/include/msvcrt/float.h
@@ -140,6 +140,9 @@ _ACRTIMP int __cdecl __fpe_flt_rounds(void);
 unsigned int __cdecl _control87(unsigned int, unsigned int);
 unsigned int __cdecl _controlfp(unsigned int, unsigned int);
 errno_t __cdecl _controlfp_s(unsigned int *, unsigned int, unsigned int);
+#ifdef __i386__
+int __cdecl __control87_2(unsigned int, unsigned int, unsigned int *, unsigned int *);
+#endif
 
 double __cdecl _copysign (double, double);
 double __cdecl _chgsign (double);




More information about the wine-cvs mailing list