Piotr Caban : ucrtbase: Copy fenv tests from msvcr120.
Alexandre Julliard
julliard at winehq.org
Wed May 19 14:55:12 CDT 2021
Module: wine
Branch: master
Commit: 9cd51b02eebc6339c21b8ebcb9438d7d5a9d666f
URL: https://source.winehq.org/git/wine.git/?a=commit;h=9cd51b02eebc6339c21b8ebcb9438d7d5a9d666f
Author: Piotr Caban <piotr at codeweavers.com>
Date: Tue May 18 21:07:04 2021 +0200
ucrtbase: Copy fenv tests from msvcr120.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ucrtbase/tests/misc.c | 167 +++++++++++++++++++++++++++++++++++++++++++++
include/msvcrt/fenv.h | 1 +
2 files changed, 168 insertions(+)
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index 5fcec2e2bb5..aaa8ada2a8a 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -1371,6 +1371,172 @@ static void test_thread_storage(void)
"can't find se_translator in thread storage\n");
}
+static unsigned long fenv_encode(unsigned int e)
+{
+ ok(!(e & ~FE_ALL_EXCEPT), "incorrect argument: %x\n", e);
+
+#if defined(__i386__)
+ return e<<24 | e<<16 | e;
+#else
+ return e<<24 | e;
+#endif
+}
+
+static void test_fenv(void)
+{
+#if defined(__i386__) || defined(__x86_64__)
+ static const int tests[] = {
+ 0,
+ FE_INEXACT,
+ FE_UNDERFLOW,
+ FE_OVERFLOW,
+ FE_DIVBYZERO,
+ FE_INVALID,
+ FE_ALL_EXCEPT,
+ };
+ static const struct {
+ fexcept_t except;
+ unsigned int flag;
+ unsigned int get;
+ fexcept_t expect;
+ } tests2[] = {
+ /* except flag get expect */
+ { 0, 0, 0, 0 },
+ { FE_ALL_EXCEPT, FE_INEXACT, 0, 0 },
+ { FE_ALL_EXCEPT, FE_INEXACT, FE_ALL_EXCEPT, FE_INEXACT },
+ { FE_ALL_EXCEPT, FE_INEXACT, FE_INEXACT, FE_INEXACT },
+ { FE_ALL_EXCEPT, FE_INEXACT, FE_OVERFLOW, 0 },
+ { FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_ALL_EXCEPT },
+ { FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_INEXACT, FE_INEXACT },
+ { FE_ALL_EXCEPT, FE_ALL_EXCEPT, 0, 0 },
+ { FE_ALL_EXCEPT, FE_ALL_EXCEPT, ~0, FE_ALL_EXCEPT },
+ { FE_ALL_EXCEPT, FE_ALL_EXCEPT, ~FE_ALL_EXCEPT, 0 },
+ { FE_INEXACT, FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_INEXACT },
+ { FE_INEXACT, FE_UNDERFLOW, FE_ALL_EXCEPT, 0 },
+ { FE_UNDERFLOW, FE_INEXACT, FE_ALL_EXCEPT, 0 },
+ { FE_INEXACT|FE_UNDERFLOW, FE_UNDERFLOW, FE_ALL_EXCEPT, FE_UNDERFLOW },
+ { FE_UNDERFLOW, FE_INEXACT|FE_UNDERFLOW, FE_ALL_EXCEPT, FE_UNDERFLOW },
+ };
+ fenv_t env, env2;
+ fexcept_t except;
+ int i, ret, flags;
+
+ _clearfp();
+
+ ret = fegetenv(&env);
+ ok(!ret, "fegetenv returned %x\n", ret);
+ if (env._Fe_ctl >> 24 != (env._Fe_ctl & 0xff))
+ {
+ win_skip("fenv_t format not supported (too old ucrtbase)\n");
+ return;
+ }
+ fesetround(FE_UPWARD);
+ ok(!env._Fe_stat, "env._Fe_stat = %lx\n", env._Fe_stat);
+ ret = fegetenv(&env2);
+ ok(!ret, "fegetenv returned %x\n", ret);
+ ok(env._Fe_ctl != env2._Fe_ctl, "fesetround didn't change _Fe_ctl (%lx).", env._Fe_ctl);
+ ret = fesetenv(&env);
+ ok(!ret, "fesetenv returned %x\n", ret);
+ ret = fegetround();
+ ok(ret == FE_TONEAREST, "Got unexpected round mode %#x.\n", ret);
+
+ except = fenv_encode(FE_ALL_EXCEPT);
+ ret = fesetexceptflag(&except, FE_INEXACT|FE_UNDERFLOW);
+ ok(!ret, "fesetexceptflag returned %x\n", ret);
+ except = fetestexcept(FE_ALL_EXCEPT);
+ ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except);
+
+ ret = feclearexcept(~FE_ALL_EXCEPT);
+ ok(!ret, "feclearexceptflag returned %x\n", ret);
+ except = fetestexcept(FE_ALL_EXCEPT);
+ ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except);
+
+ /* no crash, but no-op */
+ ret = fesetexceptflag(NULL, 0);
+ ok(!ret, "fesetexceptflag returned %x\n", ret);
+ except = fetestexcept(FE_ALL_EXCEPT);
+ ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except);
+
+ /* zero clears all */
+ except = 0;
+ ret = fesetexceptflag(&except, FE_ALL_EXCEPT);
+ ok(!ret, "fesetexceptflag returned %x\n", ret);
+ except = fetestexcept(FE_ALL_EXCEPT);
+ ok(!except, "expected 0, got %lx\n", except);
+
+ ret = fetestexcept(FE_ALL_EXCEPT);
+ ok(!ret, "fetestexcept returned %x\n", ret);
+
+ flags = 0;
+ /* adding bits with flags */
+ for(i=0; i<ARRAY_SIZE(tests); i++) {
+ except = fenv_encode(FE_ALL_EXCEPT);
+ ret = fesetexceptflag(&except, tests[i]);
+ ok(!ret, "Test %d: fesetexceptflag returned %x\n", i, ret);
+
+ ret = fetestexcept(tests[i]);
+ ok(ret == tests[i], "Test %d: expected %x, got %x\n", i, tests[i], ret);
+
+ flags |= tests[i];
+ ret = fetestexcept(FE_ALL_EXCEPT);
+ ok(ret == flags, "Test %d: expected %x, got %x\n", i, flags, ret);
+
+ except = ~0;
+ ret = fegetexceptflag(&except, ~0);
+ ok(!ret, "Test %d: fegetexceptflag returned %x.\n", i, ret);
+ ok(except == fenv_encode(flags),
+ "Test %d: expected %x, got %lx\n", i, flags, except);
+
+ except = ~0;
+ ret = fegetexceptflag(&except, tests[i]);
+ ok(!ret, "Test %d: fegetexceptflag returned %x.\n", i, ret);
+ ok(except == fenv_encode(tests[i]),
+ "Test %d: expected %x, got %lx\n", i, tests[i], except);
+ }
+
+ for(i=0; i<ARRAY_SIZE(tests); i++) {
+ ret = feclearexcept(tests[i]);
+ ok(!ret, "Test %d: feclearexceptflag returned %x\n", i, ret);
+
+ flags &= ~tests[i];
+ except = fetestexcept(tests[i]);
+ ok(!except, "Test %d: expected %x, got %lx\n", i, flags, except);
+ }
+
+ except = fetestexcept(FE_ALL_EXCEPT);
+ ok(!except, "expected 0, got %lx\n", except);
+
+ /* setting bits with except */
+ for(i=0; i<ARRAY_SIZE(tests); i++) {
+ except = fenv_encode(tests[i]);
+ ret = fesetexceptflag(&except, FE_ALL_EXCEPT);
+ ok(!ret, "Test %d: fesetexceptflag returned %x\n", i, ret);
+
+ ret = fetestexcept(tests[i]);
+ ok(ret == tests[i], "Test %d: expected %x, got %x\n", i, tests[i], ret);
+
+ ret = fetestexcept(FE_ALL_EXCEPT);
+ ok(ret == tests[i], "Test %d: expected %x, got %x\n", i, tests[i], ret);
+ }
+
+ for(i=0; i<ARRAY_SIZE(tests2); i++) {
+ _clearfp();
+
+ except = fenv_encode(tests2[i].except);
+ ret = fesetexceptflag(&except, tests2[i].flag);
+ ok(!ret, "Test %d: fesetexceptflag returned %x\n", i, ret);
+
+ ret = fetestexcept(tests2[i].get);
+ ok(ret == tests2[i].expect, "Test %d: expected %lx, got %x\n", i, tests2[i].expect, ret);
+ }
+
+ ret = feclearexcept(FE_ALL_EXCEPT);
+ ok(!ret, "feclearexceptflag returned %x\n", ret);
+ except = fetestexcept(FE_ALL_EXCEPT);
+ ok(!except, "expected 0, got %lx\n", except);
+#endif
+}
+
START_TEST(misc)
{
int arg_c;
@@ -1411,4 +1577,5 @@ START_TEST(misc)
test__o_malloc();
test_clock();
test_thread_storage();
+ test_fenv();
}
diff --git a/include/msvcrt/fenv.h b/include/msvcrt/fenv.h
index a6b53eca567..2039a1fb4c8 100644
--- a/include/msvcrt/fenv.h
+++ b/include/msvcrt/fenv.h
@@ -36,6 +36,7 @@ _ACRTIMP int __cdecl fegetenv(fenv_t*);
_ACRTIMP int __cdecl fesetenv(const fenv_t*);
_ACRTIMP int __cdecl fegetexceptflag(fexcept_t*, int);
_ACRTIMP int __cdecl fegetround(void);
+_ACRTIMP int __cdecl feholdexcept(fenv_t*);
_ACRTIMP int __cdecl fesetround(int);
_ACRTIMP int __cdecl fesetexceptflag(const fexcept_t*, int);
_ACRTIMP int __cdecl feclearexcept(int);
More information about the wine-cvs
mailing list