diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/.distdep | 56 | ||||
-rw-r--r-- | test/dtypes.c | 128 |
2 files changed, 150 insertions, 34 deletions
diff --git a/test/.distdep b/test/.distdep index a451de2..dad6bc8 100644 --- a/test/.distdep +++ b/test/.distdep @@ -390,34 +390,6 @@ big.o: \ ../src/H5Spublic.h \ ../src/H5Tpublic.h \ ../src/H5private.h -dtypes.o: \ - dtypes.c \ - ../src/hdf5.h \ - ../src/H5public.h \ - ../src/H5config.h \ - ../src/H5Ipublic.h \ - ../src/H5Apublic.h \ - ../src/H5ACpublic.h \ - ../src/H5Bpublic.h \ - ../src/H5Dpublic.h \ - ../src/H5Epublic.h \ - ../src/H5Fpublic.h \ - ../src/H5Gpublic.h \ - ../src/H5HGpublic.h \ - ../src/H5HLpublic.h \ - ../src/H5MFpublic.h \ - ../src/H5MMpublic.h \ - ../src/H5Opublic.h \ - ../src/H5Ppublic.h \ - ../src/H5Zpublic.h \ - ../src/H5Spublic.h \ - ../src/H5Tpublic.h \ - ../src/H5Tpkg.h \ - ../src/H5HGprivate.h \ - ../src/H5Fprivate.h \ - ../src/H5private.h \ - ../src/H5Tprivate.h \ - ../src/H5Gprivate.h testhdf5.o: \ testhdf5.c \ testhdf5.h \ @@ -470,3 +442,31 @@ dsets.o: \ ../src/H5Zpublic.h \ ../src/H5Spublic.h \ ../src/H5Tpublic.h +dtypes.o: \ + dtypes.c \ + ../src/hdf5.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5Ipublic.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ + ../src/H5Fpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MFpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5private.h \ + ../src/H5Tprivate.h \ + ../src/H5Gprivate.h diff --git a/test/dtypes.c b/test/dtypes.c index 4963d35..f06c8bb 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -8,6 +8,7 @@ * Purpose: Tests the data type interface (H5T) */ #include <assert.h> +#include <float.h> #include <hdf5.h> #include <math.h> #include <signal.h> @@ -60,16 +61,22 @@ typedef enum flt_t { /* Count the number of overflows */ static int noverflows_g = 0; +/* Skip overflow tests if non-zero */ +static int skip_overflow_tests_g = 0; + /* - * Some machines generate SIGFPE on floating point overflows. According to - * the Posix standard, we cannot assume that we can continue from such a - * signal. Therefore, if the following constant is defined then tests that - * might raise SIGFPE are executed in a child process. + * Although we check whether a floating point overflow generates a SIGFPE and + * turn off overflow tests in that case, it might still be possible for an + * overflow condition to occur. Once a SIGFPE is raised the program cannot + * be allowed to continue (cf. Posix signals) so in order to recover from a + * SIGFPE we run tests that might generate one in a child process. */ #if defined(HAVE_FORK) && defined(HAVE_WAITPID) # define HANDLE_SIGFPE #endif +void some_dummy_func(float x); + /*------------------------------------------------------------------------- * Function: fpe_handler @@ -89,7 +96,7 @@ static void fpe_handler(int __unused__ signo) { puts(" -SKIP-"); - puts(" Test skipped due to SIGFPE from probable overflow."); + puts(" Test skipped due to SIGFPE."); #ifndef HANDLE_SIGFPE puts(" Remaining tests could not be run."); puts(" Please turn off SIGFPE on overflows and try again."); @@ -124,6 +131,88 @@ overflow_handler(hid_t __unused__ src_id, hid_t __unused__ dst_id, /*------------------------------------------------------------------------- + * Function: some_dummy_func + * + * Purpose: A dummy function to help check for overflow. + * + * Note: DO NOT DECLARE THIS FUNCTION STATIC OR THE COMPILER MIGHT + * PROMOTE ARGUMENT `x' TO DOUBLE AND DEFEAT THE OVERFLOW + * CHECKING. + * + * Return: void + * + * Programmer: Robb Matzke + * Tuesday, July 21, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +some_dummy_func(float x) +{ + char s[128]; + sprintf(s, "%g", x); +} + + +/*------------------------------------------------------------------------- + * Function: generates_sigfpe + * + * Purpose: Determines if SIGFPE is generated from overflows. We must be + * able to fork() and waitpid() in order for this test to work + * properly. Sets skip_overflow_tests_g to non-zero if they + * would generate SIGBUS, zero otherwise. + * + * Programmer: Robb Matzke + * Tuesday, July 21, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +generates_sigfpe(void) +{ +#if defined(HAVE_FORK) && defined(HAVE_WAITPID) + pid_t pid; + int status; + size_t i, j; + double d; + unsigned char *dp = (unsigned char*)&d; + float f; + + fflush(stdout); + fflush(stderr); + if ((pid=fork())<0) { + perror("fork"); + exit(1); + } else if (0==pid) { + for (i=0; i<2000; i++) { + for (j=0; j<sizeof(double); j++) dp[j] = rand(); + f = (float)d; + some_dummy_func(f); + } + exit(0); + } + + while (pid!=waitpid(pid, &status, 0)) /*void*/; + if (WIFEXITED(status) && 0==WEXITSTATUS(status)) { + printf("Overflow cases will be tested.\n"); + skip_overflow_tests_g = FALSE; + } else if (WIFSIGNALED(status) && SIGFPE==WTERMSIG(status)) { + printf("Overflow cases cannot be safely tested.\n"); + skip_overflow_tests_g = TRUE; + } +#else + printf("Cannot determine if overflows generate a SIGFPE; assuming yes.\n"); + printf("Overflow cases will not be tested.\n"); + skip_overflow_tests_g = TRUE; +#endif +} + + +/*------------------------------------------------------------------------- * Function: cleanup * * Purpose: Removes test files @@ -961,7 +1050,31 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst) * will be used for the conversion while the `saved' buffer will be * used for the comparison later. */ - for (j=0; j<nelmts*src_size; j++) buf[j] = saved[j] = rand(); + if (!skip_overflow_tests_g) { + for (j=0; j<nelmts*src_size; j++) buf[j] = saved[j] = rand(); + } else { + for (j=0; j<nelmts; j++) { + unsigned char temp[32]; + if (src_size<=dst_size) { + for (k=0; k<dst_size; k++) buf[j*src_size+k] = rand(); + } else { + for (k=0; k<dst_size; k++) temp[k] = rand(); + if (FLT_DOUBLE==src_type && FLT_FLOAT==dst_type) { + hw_d = *((float*)temp); + memcpy(buf+j*src_size, &hw_d, src_size); +#ifdef USE_LDOUBLE + } else if (FLT_LDOUBLE==src_type && FLT_FLOAT==dst_type) { + hw_ld = *((float*)temp); + memcpy(buf+j*src_size, &hw_ld, src_size); + } else if (FLT_LDOUBLE==src_type && FLT_DOUBLE==dst_type) { + hw_ld = *((double*)temp); + memcpy(buf+j*src_size, &hw_ld, src_size); +#endif + } + } + memcpy(saved+j*src_size, buf+j*src_size, src_size); + } + } /* Perform the conversion in software */ if (H5Tconvert(src, dst, nelmts, buf, NULL)<0) goto error; @@ -1199,6 +1312,9 @@ main(void) nerrors += test_named ()<0 ? 1 : 0; nerrors += test_conv_int ()<0 ? 1 : 0; + /* Does floating point overflow generate a SIGFPE? */ + generates_sigfpe(); + /* Test degenerate cases */ nerrors += test_conv_flt_1("noop", H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT); nerrors += test_conv_flt_1("noop", H5T_NATIVE_DOUBLE, H5T_NATIVE_DOUBLE); |