[svn-r11345] Purpose:

Bug fix & code cleanup

Description:
    Address most of datatype conversion exception handling bug that Ed
Hartnett reported.  (He's reported a different problem now, but we're closer
at least).

    Also, condense exception handling #ifdef's into one location instead of
spread out in so many places.

Platforms tested:
    FreeBSD 4.11 (sleipnir)
    Too minor to require h5committest
This commit is contained in:
Quincey Koziol 2005-09-03 12:11:00 -05:00
parent 4aa86e2297
commit 01a3d9d780
3 changed files with 290 additions and 54 deletions

View File

@ -190,7 +190,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
* equal. In this case, do not return exception but make sure the maximum is assigned
* to the destination. SLU - 2005/06/29
*/
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_Xx_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
if(cb_struct.func) { \
@ -207,8 +206,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} \
else \
*((DT*)D) = (D_MAX); \
} else if (*((ST*)S) == (DT)(D_MAX)) { \
*((DT*)D) = (D_MAX); \
} else if (*((ST*)S) < (DT)(D_MIN)) { \
if(cb_struct.func) { \
H5T_conv_ret_t except_ret; /*callback return*/ \
@ -227,13 +224,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#else
#define H5T_CONV_Xx_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#endif
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_Ux_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
if(cb_struct.func) { \
@ -253,18 +244,12 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#else
#define H5T_CONV_Ux_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#endif
#define H5T_CONV_sS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
H5T_CONV(H5T_CONV_xX, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_sU_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) < 0) { \
if(cb_struct.func) { \
@ -284,18 +269,12 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#else
#define H5T_CONV_sU_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#endif
#define H5T_CONV_sU(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
H5T_CONV(H5T_CONV_sU, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_uS_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (sizeof(ST)==sizeof(DT) && *((ST*)S) > (D_MAX)) { \
if(cb_struct.func) { \
@ -315,11 +294,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#else
#define H5T_CONV_uS_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#endif
#define H5T_CONV_uS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
@ -336,7 +310,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
H5T_CONV(H5T_CONV_Xx, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_Su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) < 0) { \
if(cb_struct.func) { \
@ -371,11 +344,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#else
#define H5T_CONV_Su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#endif
#define H5T_CONV_Su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
@ -392,7 +360,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
H5T_CONV(H5T_CONV_Ux, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
/* Assumes memory format of unsigned & signed integers is same */ \
if (*((ST*)S) < 0) { \
@ -413,18 +380,12 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#else
#define H5T_CONV_su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#endif
#define H5T_CONV_su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)==sizeof(DT)); \
H5T_CONV(H5T_CONV_su, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_us_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
/* Assumes memory format of unsigned & signed integers is same */ \
if (*((ST*)S) > (DT)(D_MAX)) { \
@ -445,11 +406,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#else
#define H5T_CONV_us_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#endif
#define H5T_CONV_us(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)==sizeof(DT)); \
@ -464,7 +420,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
/* Same as H5T_CONV_Xx_CORE, except that instead of using D_MAX and D_MIN
* when an overflow occurs, use the 'float' infinity values.
*/
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_Ff_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
if(cb_struct.func) { \
@ -499,23 +454,119 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#else
#define H5T_CONV_Ff_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#endif
#define H5T_CONV_Ff(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
H5T_CONV(H5T_CONV_Ff, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
/* Note: this is a relative fragile hack (to use the temporary variable of the
* destination type) - it may get optimized out by the compiler. QAK - 2005/08/19
*
* A better solution would be to find the bit position of the highest 1 bit
* in the source and the bit position of the lowest 1 bit in the source and
* determine if the number of bits between them is greater than the mantissa
* of the floating point number (including the leading "implied" 1 bit), then
* issue a precision exception. However, that's probably too slow, so we'll
* try to use this solution for now. QAK - 2005/19/08
*/
#define H5T_CONV_xF_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
DT t_s = *((ST*)S); \
if (*((ST*)S) != (ST)t_s) { \
if(cb_struct.func) { \
H5T_conv_ret_t except_ret; /*callback return*/ \
\
except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_PRECISION, \
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
*((DT*)D) = (DT)(*((ST*)S)); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
} \
else \
*((DT*)D) = (DT)(*((ST*)S)); \
} \
else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#define H5T_CONV_xF(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
H5T_CONV(H5T_CONV_xX, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
H5T_CONV(H5T_CONV_xF, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
/* Added a condition branch(else if (*((ST*)S) == (DT)(D_MAX))) which seems redundant.
* It handles a special situation when the source is "float" and assigned the value
* of "INT_MAX". A compiler may do roundup making this value "INT_MAX+1". However,
* when do comparison "if (*((ST*)S) > (DT)(D_MAX))", the compiler may consider them
* equal. In this case, do not return exception but make sure the maximum is assigned
* to the destination. SLU - 2005/06/29
*
* Modified Ray's change to just check for the source >= the DT_MAX, so that
* the exception handling routine gets called. QAK - 2005/08/08
*/
#define H5T_CONV_Fx_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) >= (DT)(D_MAX)) { \
if(cb_struct.func) { \
H5T_conv_ret_t except_ret; /*callback return*/ \
\
except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, \
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
*((DT*)D) = (D_MAX); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
} \
else \
*((DT*)D) = (D_MAX); \
} else if (*((ST*)S) < (DT)(D_MIN)) { \
if(cb_struct.func) { \
H5T_conv_ret_t except_ret; /*callback return*/ \
\
except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, \
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
*((DT*)D) = (D_MIN); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
} \
else \
*((DT*)D) = (D_MIN); \
} else if (*((ST*)S) != (ST)((DT)(*((ST*)S)))) { \
if(cb_struct.func) { \
H5T_conv_ret_t except_ret; /*callback return*/ \
\
except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_TRUNCATE, \
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
*((DT*)D) = (DT)(*((ST*)S)); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
} \
else \
*((DT*)D) = (DT)(*((ST*)S)); \
} \
else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#define H5T_CONV_Fx(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
H5T_CONV(H5T_CONV_Xx, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
H5T_CONV(H5T_CONV_Fx, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
/* Since all "no exception" cores do the same thing (assign the value in the
* source location to the destination location, using casting), use one "core"
* to do them all.
*/
#define H5T_CONV_NO_EXCEPT_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
*((DT*)D) = (DT)(*((ST*)S)); \
}
/* The main part of every integer hardware conversion macro */
@ -686,7 +737,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
H5_GLUE(H5T_CONV_LOOP_,PRE_DALIGN_GUTS)(DT) \
\
/* ... user-defined stuff here -- the conversion ... */ \
H5_GLUE(GUTS,_CORE)(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
H5T_CONV_LOOP_GUTS(GUTS,S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
\
/* Handle source post-alignment */ \
H5_GLUE(H5T_CONV_LOOP_,POST_SALIGN_GUTS)(ST) \
@ -699,6 +750,16 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
dst += d_stride; \
}
/* Macro to call the actual "guts" of the type conversion, or call the "no exception" guts */
#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_LOOP_GUTS(GUTS,S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
/* ... user-defined stuff here -- the conversion ... */ \
H5_GLUE(GUTS,_CORE)(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX)
#else /* H5_WANT_DCONV_EXCEPTION */
#define H5T_CONV_LOOP_GUTS(GUTS,S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
H5_GLUE(H5T_CONV_NO_EXCEPT,_CORE)(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX)
#endif /* H5_WANT_DCONV_EXCEPTION */
#ifdef H5T_DEBUG

View File

@ -4749,7 +4749,7 @@ run_fp_int_conv(const char *name)
* Modifications:
* Raymond Lu
* Monday, April 4, 2005
* These tests were slitted from dtypes.c because dtypes.c
* These tests were split from dtypes.c because dtypes.c
* has grown too big.
*
*-------------------------------------------------------------------------

View File

@ -86,6 +86,9 @@ typedef enum dtype_t {
FLT_LDOUBLE, OTHER
} dtype_t;
/* Constant for size of conversion buffer for int <-> float exception test */
#define CONVERT_SIZE 4
/* Count opaque conversions */
static int num_opaque_conversions_g = 0;
@ -3832,6 +3835,177 @@ test_encode(void)
return 1;
}
typedef struct {
unsigned num_range_hi; /* Number of H5T_CONV_EXCEPT_RANGE_HI exceptions seen */
unsigned num_range_low; /* Number of H5T_CONV_EXCEPT_RANGE_LOW exceptions seen */
unsigned num_precision; /* Number of H5T_CONV_EXCEPT_PRECISION exceptions seen */
unsigned num_truncate; /* Number of H5T_CONV_EXCEPT_TRUNCATE exceptions seen */
unsigned num_other; /* Number of other exceptions seen */
} except_info_t;
static H5T_conv_ret_t
conv_except(H5T_conv_except_t except_type, hid_t UNUSED src_id, hid_t UNUSED dst_id,
void UNUSED *src_buf, void UNUSED *dst_buf, void *_user_data)
{
except_info_t *user_data = (except_info_t *)_user_data;
if(except_type == H5T_CONV_EXCEPT_RANGE_HI)
user_data->num_range_hi++;
else if(except_type == H5T_CONV_EXCEPT_RANGE_LOW)
user_data->num_range_low++;
else if(except_type == H5T_CONV_EXCEPT_PRECISION)
user_data->num_precision++;
else if(except_type == H5T_CONV_EXCEPT_TRUNCATE)
user_data->num_truncate++;
else
user_data->num_other++;
return(H5T_CONV_UNHANDLED);
}
/*-------------------------------------------------------------------------
* Function: test_int_float_except
*
* Purpose: Tests exception handling behavior of int <-> float
* conversions.
*
* Return: Success: 0
*
* Failure: number of errors
*
* Programmer: Quincey Koziol
* August 18, 2005
*
* Notes: This routine is pretty specific to 4 byte integers and 4 byte
* floats and I can't think of a particularly good way to
* make it portable to other architectures, but further
* input and changes are welcome. -QAK
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
test_int_float_except(void)
{
#if H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4
float buf[CONVERT_SIZE] = {(float)INT_MIN - 172.0, (float)INT_MAX - 32.0,
(float)INT_MAX - 68.0, (float)4.5};
int buf_int[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX-127, 4};
float buf_float[CONVERT_SIZE] = {INT_MIN, INT_MAX + 1.0, INT_MAX - 127.0, 4};
int *intp; /* Pointer to buffer, as integers */
int buf2[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 72, 0};
float buf2_float[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 127.0, 0.0};
int buf2_int[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 127, 0};
float *floatp; /* Pointer to buffer #2, as floats */
hid_t dxpl; /* Dataset transfer property list */
except_info_t e; /* Exception information */
unsigned u; /* Local index variables */
#endif /* H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4 */
TESTING("exceptions for int <-> float conversions");
#if H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4
/* Create dataset transfer property list */
if((dxpl = H5Pcreate(H5P_DATASET_XFER) ) < 0) TEST_ERROR
/* Set the conversion exception handler in the DXPL */
if(H5Pset_type_conv_cb(dxpl, conv_except, &e) < 0) TEST_ERROR
/* Convert buffer */
HDmemset(&e, 0, sizeof(except_info_t));
if(H5Tconvert(H5T_NATIVE_FLOAT, H5T_NATIVE_INT, (size_t)CONVERT_SIZE, buf, NULL, dxpl) < 0) TEST_ERROR
/* Check the buffer after conversion, as integers */
for(u = 0; u < CONVERT_SIZE; u++) {
intp = (int *)&buf[u];
if(*intp != buf_int[u]) TEST_ERROR
} /* end for */
/* Check for proper exceptions */
if(e.num_range_hi != 1) TEST_ERROR
if(e.num_range_low != 1) TEST_ERROR
if(e.num_precision != 0) TEST_ERROR
if(e.num_truncate != 1) TEST_ERROR
if(e.num_other != 0) TEST_ERROR
/* Convert buffer */
HDmemset(&e, 0, sizeof(except_info_t));
if(H5Tconvert(H5T_NATIVE_INT, H5T_NATIVE_FLOAT, (size_t)CONVERT_SIZE,
buf, NULL, dxpl) < 0) TEST_ERROR
/* Check the buffer after conversion, as floats */
for(u = 0; u < CONVERT_SIZE; u++) {
floatp = (float *)&buf[u];
if(*floatp != buf_float[u]) TEST_ERROR
} /* end for */
/* Check for proper exceptions */
if(e.num_range_hi != 0) TEST_ERROR
if(e.num_range_low != 0) TEST_ERROR
if(e.num_precision != 1) TEST_ERROR
if(e.num_truncate != 0) TEST_ERROR
if(e.num_other != 0) TEST_ERROR
/* Work on second buffer */
/* Convert second buffer */
HDmemset(&e, 0, sizeof(except_info_t));
if(H5Tconvert(H5T_NATIVE_INT, H5T_NATIVE_FLOAT, (size_t)CONVERT_SIZE,
buf2, NULL, dxpl) < 0) TEST_ERROR
/* Check the buffer after conversion, as floats */
for(u = 0; u < CONVERT_SIZE; u++) {
floatp = (float *)&buf2[u];
if(*floatp != buf2_float[u]) TEST_ERROR
} /* end for */
/* Check for proper exceptions */
if(e.num_range_hi != 0) TEST_ERROR
if(e.num_range_low != 0) TEST_ERROR
if(e.num_precision != 2) TEST_ERROR
if(e.num_truncate != 0) TEST_ERROR
if(e.num_other != 0) TEST_ERROR
/* Convert buffer */
HDmemset(&e, 0, sizeof(except_info_t));
if(H5Tconvert(H5T_NATIVE_FLOAT, H5T_NATIVE_INT, (size_t)CONVERT_SIZE,
buf2, NULL, dxpl) < 0) TEST_ERROR
/* Check the buffer after conversion, as integers */
for(u = 0; u < CONVERT_SIZE; u++) {
intp = (int *)&buf2[u];
if(*intp != buf2_int[u]) TEST_ERROR
} /* end for */
/* Check for proper exceptions */
if(e.num_range_hi != 1) TEST_ERROR
if(e.num_range_low != 0) TEST_ERROR
if(e.num_precision != 0) TEST_ERROR
if(e.num_truncate != 0) TEST_ERROR
if(e.num_other != 0) TEST_ERROR
/* Close DXPL */
if(H5Pclose(dxpl) < 0) TEST_ERROR
PASSED();
#else /* H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4 */
SKIPPED();
HDputs(" Test skipped due to int or float not 4 bytes.");
#endif /* H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4 */
return 0;
#if H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4
error:
H5E_BEGIN_TRY {
H5Pclose (dxpl);
} H5E_END_TRY;
return 1;
#endif /* H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4 */
} /* end test_int_float_except() */
/*-------------------------------------------------------------------------
* Function: main
@ -3873,6 +4047,7 @@ main(void)
nerrors += test_transient (fapl);
nerrors += test_named (fapl);
nerrors += test_encode();
nerrors += test_int_float_except();
h5_cleanup(FILENAME, fapl); /*must happen before first reset*/
reset_hdf5();