fix fenv.c tests according to a new interpretation of the standard
[libc-test] / src / math / fenv.c
index c221d7f..9603504 100644 (file)
@@ -1,7 +1,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdarg.h>
-#include "util.h"
+#include "mtest.h"
 
 static int test_status;
 
@@ -37,14 +37,16 @@ static struct {
 #ifdef FE_UNDERFLOW
        F(FE_UNDERFLOW),
 #endif
+       {0, 0}
 };
 
 static void test_except()
 {
        #pragma STDC FENV_ACCESS ON
        int i,r;
+       fenv_t env;
 
-       for (i=0; i < sizeof te/sizeof*te; i++) {
+       for (i=0; te[i].i; i++) {
                feclearexcept(FE_ALL_EXCEPT);
 
                r = feraiseexcept(te[i].i);
@@ -55,6 +57,28 @@ static void test_except()
                        error("feraiseexcept(%s) want %d got %d\n",
                                te[i].name, te[i].i, r);
        }
+
+       r = feraiseexcept(FE_ALL_EXCEPT);
+       if (r != 0)
+               error("feraisexcept(FE_ALL_EXCEPT) failed\n");
+       r = fegetenv(&env);
+       if (r != 0)
+               error("fegetenv(&env) = %d\n", r);
+       r = fetestexcept(FE_ALL_EXCEPT);
+       if (r != FE_ALL_EXCEPT)
+               error("fetestexcept failed: got 0x%x, want 0x%x (FE_ALL_ECXEPT)\n", r, FE_ALL_EXCEPT);
+       r = fesetenv(FE_DFL_ENV);
+       if (r != 0)
+               error("fesetenv(FE_DFL_ENV) = %d\n", r);
+       r = fetestexcept(FE_ALL_EXCEPT);
+       if (r != 0)
+               error("fesetenv(FE_DFL_ENV) did not clear exceptions: 0x%x\n", r);
+       r = fesetenv(&env);
+       if (r != 0)
+               error("fesetenv(&env) = %d\n", r);
+       r = fetestexcept(FE_ALL_EXCEPT);
+       if (r != FE_ALL_EXCEPT)
+               error("fesetenv(&env) did not restore exceptions: 0x%x\n", r);
 }
 
 static struct {
@@ -77,6 +101,7 @@ static void test_round()
 {
        #pragma STDC FENV_ACCESS ON
        int i,r;
+       fenv_t env;
 
        for (i=0; i < sizeof tr/sizeof*tr; i++) {
                if (tr[i].i < 0)
@@ -90,11 +115,28 @@ static void test_round()
        for (i=0; i < sizeof tr/sizeof*tr; i++) {
                r = fesetround(tr[i].i);
                if (r != 0)
-                       error("fesetround %d\n", r);
+                       error("fesetround(%s) = %d\n", tr[i].name, r);
                r = fegetround();
                if (r != tr[i].i)
-                       error("fegetround %x wanted %x\n", r, tr[i].i);
+                       error("fegetround() = 0x%x, wanted 0x%x (%s)\n", r, tr[i].i, tr[i].name);
        }
+
+       r = fegetenv(&env);
+       if (r != 0)
+               error("fegetenv(&env) = %d\n", r);
+       i = fegetround();
+       r = fesetenv(FE_DFL_ENV);
+       if (r != 0)
+               error("fesetenv(FE_DFL_ENV) = %d\n", r);
+       r = fegetround();
+       if (r != FE_TONEAREST)
+               error("fesetenv(FE_DFL_ENV) did not set FE_TONEAREST (0x%x), got 0x%x\n", FE_TONEAREST, r);
+       r = fesetenv(&env);
+       if (r != 0)
+               error("fesetenv(&env) = %d\n", r);
+       r = fegetround();
+       if (r != i)
+               error("fesetenv(&env) did not restore 0x%x, got 0x%x\n", i, r);
 }
 
 /* ieee double precision add operation */
@@ -164,10 +206,42 @@ static void test_round_add(void)
        }
 }
 
+static void test_bad(void)
+{
+       fexcept_t f;
+       int r;
+
+       r = feclearexcept(FE_ALL_EXCEPT);
+       if (r != 0)
+               error("feclearexcept(FE_ALL_EXCEPT) failed\n");
+       r = fetestexcept(-1);
+       if (r != 0)
+               error("fetestexcept(-1) should return 0 when all exceptions are cleared, got %d\n", r);
+       r = feraiseexcept(1234567|FE_ALL_EXCEPT);
+       if (r != 0)
+               error("feraiseexcept returned non-zero for non-supported exceptions: %d\n", r);
+       r = feclearexcept(1234567|FE_ALL_EXCEPT);
+       if (r != 0)
+               error("feclearexcept returned non-zero for non-supported exceptions: %d\n", r);
+       r = fesetround(1234567);
+       if (r == 0)
+               error("fesetround should fail on invalid rounding mode\n");
+       r = fegetexceptflag(&f, 1234567);
+       if (r != 0)
+               error("fegetexceptflag returned non-zero for non-supported exceptions: %d\n", r);
+       r = fegetexceptflag(&f, 0);
+       if (r != 0)
+               error("fegetexceptflag(0) failed\n");
+       r = fesetexceptflag(&f, 1234567);
+       if (r != 0)
+               error("fesetexceptflag returned non-zero fir non-supported exceptions: %d\n", r);
+}
+
 int main(void)
 {
        test_except();
        test_round();
        test_round_add();
+       test_bad();
        return test_status;
 }