Compare commits

...

17 Commits

Author SHA1 Message Date
github-actions
81d197c1dd Committing clang-format changes 2022-04-20 21:12:41 +00:00
David Young
1a6d20b229 Simplify. Removing the integer detection paved the way for this. 2022-04-20 16:07:17 -05:00
David Young
85c2171a17 Quiet a GCC warning: don't turn back on compiler diagnostics that
weren't turned off to begin with.
2022-04-20 16:05:17 -05:00
David Young
066f824170 Move the alignment computation for miscellaneous types from
H5detect.c to H5Tnative.c and rename H5T__init_native_int() to
H5T__init_native_internal() to try to match its more general purpose.
2022-04-20 16:02:36 -05:00
David Young
cbaeb279ae Extract struct-offset arithmetic into macro TAG_ALIGNMENT for reuse in a
later commit.
2022-04-19 12:20:12 -05:00
David Young
be65814cde Merge remote-tracking branch 'thg/develop' into feature/h5detect 2022-04-14 11:49:58 -05:00
David Young
0522b9fe5d Force CI to run. 2022-03-18 17:03:56 -05:00
github-actions
b3d75b13db Committing clang-format changes 2022-03-10 16:19:29 +00:00
David Young
069f75648a Merge remote-tracking branch 'thg/develop' into feature/h5detect 2022-03-10 10:17:13 -06:00
David Young
e8bcb24e3f NFCI: write some comments. 2022-03-10 10:15:57 -06:00
David Young
9e87536a29 In a comment, put back a sentence that mentions H5Tget_native_type(). 2022-03-10 09:06:51 -06:00
David Young
a7d55c479d Briefly explain alignments_t. 2022-03-10 09:06:32 -06:00
David Young
af884602f0 To find the alignment of types, use a type instead of an object and
offsetof() instead of pointer arithmetic.  I hope that this is what MSVC
wants.
2022-01-28 14:58:47 -06:00
David Young
5be6c453ec Reorder the initializer macro to try to satisfy MSVC. Put the format
of the macro back the way it was and disable clang-format.
2022-01-28 12:33:38 -06:00
David Young
8788414eec Let the compiler check alignment in H5detect since it does not
purposefully make unaligned accesses any longer.

Remove some setjmp(3)-related code.
2022-01-28 12:19:09 -06:00
github-actions
ccc6bd88b9 Committing clang-format changes 2022-01-28 17:29:17 +00:00
David Young
558e75a9b5 Replace H5detect's build-time detection of C99 integer properties with a
table-driven routine, `H5T__init_native_int()`, that is run at library
initialization time.

Always respect the alignment used by the compiler for integers.  The
library invites trouble by using different alignment than the compiler
expects.  Here and there update a comment about alignment.

Retire the H5detect code that tries to find the least permissible
integer alignment by running experiments and catching any signals thrown
or unexpected results.
2022-01-28 11:26:07 -06:00
4 changed files with 398 additions and 718 deletions

View File

@@ -473,35 +473,21 @@ hid_t H5T_NATIVE_INT_FAST64_g = FAIL;
hid_t H5T_NATIVE_UINT_FAST64_g = FAIL;
/*
* Alignment constraints for native types. These are initialized at run time
* in H5Tinit.c. These alignments are mainly for offsets in HDF5 compound
* datatype or C structures, which are different from the alignments for memory
* address below this group of variables.
* Alignment constraints for HDF5 types. Accessing objects of these
* types with improper alignment invokes C undefined behavior, so the
* library lays out objects with correct alignment, always.
*
* A value of N indicates that the data must be aligned on an address
* ADDR such that 0 == ADDR mod N. When N=1 no alignment is required;
* N=0 implies that alignment constraints were not calculated. These
* values are used for structure alignment.
*/
size_t H5T_NATIVE_SCHAR_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_UCHAR_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_SHORT_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_USHORT_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_INT_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_UINT_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_LONG_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_ULONG_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_LLONG_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_ULLONG_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_FLOAT_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_DOUBLE_COMP_ALIGN_g = 0;
size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g = 0;
size_t H5T_POINTER_ALIGN_g = 0;
size_t H5T_HVL_ALIGN_g = 0;
size_t H5T_HOBJREF_ALIGN_g = 0;
size_t H5T_HDSETREGREF_ALIGN_g = 0;
size_t H5T_REF_ALIGN_g = 0;
size_t H5T_POINTER_COMP_ALIGN_g = 0;
size_t H5T_HVL_COMP_ALIGN_g = 0;
size_t H5T_HOBJREF_COMP_ALIGN_g = 0;
size_t H5T_HDSETREGREF_COMP_ALIGN_g = 0;
size_t H5T_REF_COMP_ALIGN_g = 0;
/*
* Alignment constraints for native types. These are initialized at run time
* in H5Tinit.c
*/
size_t H5T_NATIVE_SCHAR_ALIGN_g = 0;
size_t H5T_NATIVE_UCHAR_ALIGN_g = 0;
size_t H5T_NATIVE_SHORT_ALIGN_g = 0;
@@ -777,6 +763,9 @@ H5T_init(void)
if (H5T__init_native() < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize interface")
if (H5T__init_native_internal() < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize integers")
/* Get the atomic datatype structures needed by the initialization code below */
if (NULL == (native_schar = (H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")

View File

@@ -177,13 +177,13 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
if (H5T_IS_VL_STRING(dtype->shared)) {
/* Update size, offset and compound alignment for parent. */
if (H5T__cmp_offset(comp_size, offset, sizeof(char *), (size_t)1, H5T_POINTER_COMP_ALIGN_g,
if (H5T__cmp_offset(comp_size, offset, sizeof(char *), (size_t)1, H5T_POINTER_ALIGN_g,
struct_align) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset")
} /* end if */
else {
/* Update size, offset and compound alignment for parent. */
if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_COMP_ALIGN_g,
if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_ALIGN_g,
struct_align) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset")
} /* end else */
@@ -208,7 +208,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type")
/* Update size, offset and compound alignment for parent. */
if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_COMP_ALIGN_g,
if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_ALIGN_g,
struct_align) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset")
break;
@@ -227,7 +227,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
/* Update size, offset and compound alignment for parent. */
if (0 == H5T_cmp(ret_value, dt, FALSE)) {
align = H5T_HOBJREF_COMP_ALIGN_g;
align = H5T_HOBJREF_ALIGN_g;
ref_size = sizeof(hobj_ref_t);
} /* end if */
else {
@@ -236,12 +236,12 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type")
if (0 == H5T_cmp(ret_value, dt, FALSE)) {
align = H5T_HDSETREGREF_COMP_ALIGN_g;
align = H5T_HDSETREGREF_ALIGN_g;
ref_size = sizeof(hdset_reg_ref_t);
} /* end if */
else {
/* Only pointers to underlying opaque reference types */
align = H5T_REF_COMP_ALIGN_g;
align = H5T_REF_ALIGN_g;
ref_size = sizeof(H5R_ref_t);
} /* end else */
} /* end else */
@@ -479,7 +479,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype")
/* Update size, offset and compound alignment for parent compound type directly. */
vl_align = H5T_HVL_COMP_ALIGN_g;
vl_align = H5T_HVL_ALIGN_g;
vl_size = sizeof(hvl_t);
if (H5T__cmp_offset(comp_size, offset, vl_size, (size_t)1, vl_align, struct_align) < 0)
@@ -625,7 +625,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
else
tid = H5T_NATIVE_UCHAR;
align = H5T_NATIVE_SCHAR_COMP_ALIGN_g;
align = H5T_NATIVE_SCHAR_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_SHORT:
@@ -633,7 +633,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
tid = H5T_NATIVE_SHORT;
else
tid = H5T_NATIVE_USHORT;
align = H5T_NATIVE_SHORT_COMP_ALIGN_g;
align = H5T_NATIVE_SHORT_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_INT:
@@ -642,7 +642,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
else
tid = H5T_NATIVE_UINT;
align = H5T_NATIVE_INT_COMP_ALIGN_g;
align = H5T_NATIVE_INT_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_LONG:
@@ -651,7 +651,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
else
tid = H5T_NATIVE_ULONG;
align = H5T_NATIVE_LONG_COMP_ALIGN_g;
align = H5T_NATIVE_LONG_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_LLONG:
@@ -660,7 +660,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
else
tid = H5T_NATIVE_ULLONG;
align = H5T_NATIVE_LLONG_COMP_ALIGN_g;
align = H5T_NATIVE_LLONG_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_UNKNOWN:
@@ -764,17 +764,17 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali
switch (match) {
case H5T_NATIVE_FLOAT_MATCH_FLOAT:
tid = H5T_NATIVE_FLOAT;
align = H5T_NATIVE_FLOAT_COMP_ALIGN_g;
align = H5T_NATIVE_FLOAT_ALIGN_g;
break;
case H5T_NATIVE_FLOAT_MATCH_DOUBLE:
tid = H5T_NATIVE_DOUBLE;
align = H5T_NATIVE_DOUBLE_COMP_ALIGN_g;
align = H5T_NATIVE_DOUBLE_ALIGN_g;
break;
case H5T_NATIVE_FLOAT_MATCH_LDOUBLE:
tid = H5T_NATIVE_LDOUBLE;
align = H5T_NATIVE_LDOUBLE_COMP_ALIGN_g;
align = H5T_NATIVE_LDOUBLE_ALIGN_g;
break;
case H5T_NATIVE_FLOAT_MATCH_UNKNOWN:
@@ -940,3 +940,324 @@ H5T__cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, size_t nele
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5T__cmp_offset() */
#define TAG_ALIGNMENT(tag) (offsetof(alignments_t, tag.x) - offsetof(alignments_t, tag))
/* clang-format off */
#define NATIVE_ENTRY_INITIALIZER(tag, type, precision, has_sign) { \
.alignmentp = &H5T_NATIVE_##tag##_ALIGN_g \
, .alignment = TAG_ALIGNMENT(tag) \
, .hidp = &H5T_NATIVE_##tag##_g \
, .size = sizeof(type) \
, .atomic = { \
.offset = 0 \
, .prec = (precision != 0) ? precision : (sizeof(type) * 8) \
, .lsb_pad = H5T_PAD_ZERO \
, .msb_pad = H5T_PAD_ZERO \
, .u.i.sign = has_sign ? H5T_SGN_2 : H5T_SGN_NONE \
} \
}
/* clang-format on */
static H5T_order_t
get_host_byte_order(void)
{
static const union {
uint64_t u64;
char byte[8];
} endian_exemplar = {.byte = {1}};
return (endian_exemplar.u64 == 1) ? H5T_ORDER_LE : H5T_ORDER_BE;
}
/* Establish `H5T_t`s for C99 integer types including fixed- and
* minimum-width types (uint16_t, uint_least16_t, uint_fast16_t, ...).
*
* Also establish alignment for some miscellaneous types: pointers,
* HDF5 references, and so on.
*/
herr_t
H5T__init_native_internal(void)
{
/* Here we construct a type that lets us find alignment constraints
* without using the alignof operator, which is not available in C99.
*
* Between each sub-struct's `char` member `c` and member `x`, the
* compiler must insert padding to ensure proper alignment of `x`.
* We can find the alignment constraint of each `x` by looking at
* its offset from the beginning of its sub-struct.
*/
typedef struct {
struct {
char c;
signed char x;
} SCHAR;
struct {
char c;
unsigned char x;
} UCHAR;
struct {
char c;
short x;
} SHORT;
struct {
char c;
unsigned short x;
} USHORT;
struct {
char c;
int x;
} INT;
struct {
char c;
unsigned int x;
} UINT;
struct {
char c;
long x;
} LONG;
struct {
char c;
unsigned long x;
} ULONG;
struct {
char c;
long long x;
} LLONG;
struct {
char c;
unsigned long long x;
} ULLONG;
struct {
char c;
int8_t x;
} INT8;
struct {
char c;
uint8_t x;
} UINT8;
struct {
char c;
int_least8_t x;
} INT_LEAST8;
struct {
char c;
uint_least8_t x;
} UINT_LEAST8;
struct {
char c;
int_fast8_t x;
} INT_FAST8;
struct {
char c;
uint_fast8_t x;
} UINT_FAST8;
struct {
char c;
int16_t x;
} INT16;
struct {
char c;
uint16_t x;
} UINT16;
struct {
char c;
int_least16_t x;
} INT_LEAST16;
struct {
char c;
uint_least16_t x;
} UINT_LEAST16;
struct {
char c;
int_fast16_t x;
} INT_FAST16;
struct {
char c;
uint_fast16_t x;
} UINT_FAST16;
struct {
char c;
int32_t x;
} INT32;
struct {
char c;
uint32_t x;
} UINT32;
struct {
char c;
int_least32_t x;
} INT_LEAST32;
struct {
char c;
uint_least32_t x;
} UINT_LEAST32;
struct {
char c;
int_fast32_t x;
} INT_FAST32;
struct {
char c;
uint_fast32_t x;
} UINT_FAST32;
struct {
char c;
int64_t x;
} INT64;
struct {
char c;
uint64_t x;
} UINT64;
struct {
char c;
int_least64_t x;
} INT_LEAST64;
struct {
char c;
uint_least64_t x;
} UINT_LEAST64;
struct {
char c;
int_fast64_t x;
} INT_FAST64;
struct {
char c;
uint_fast64_t x;
} UINT_FAST64;
struct {
char c;
void *x;
} pointer;
struct {
char c;
hvl_t x;
} hvl;
struct {
char c;
hobj_ref_t x;
} hobjref;
struct {
char c;
hdset_reg_ref_t x;
} hdsetregref;
struct {
char c;
H5R_ref_t x;
} ref;
} alignments_t;
/* Describe a C99 type, `type`, and tell where to write its
* H5T_t identifier and alignment. Tables of these descriptions
* drive the initialization of `H5T_t`s.
*/
typedef struct {
/* Pointer to the global variable that receives the
* alignment of `type`:
*/
size_t *alignmentp;
size_t alignment; // natural alignment of `type`
/* Pointer to the global variable that receives the
* identifier for `type`'s H5T_t:
*/
hid_t * hidp;
size_t size; // sizeof(`type`)
H5T_atomic_t atomic; // `type` facts such as signedness
} native_int_t;
typedef struct {
const native_int_t *table;
size_t nelmts;
} native_int_table_t;
/* clang-format off */
/* The library compiles with a limit on `static` object size, so
* I broke this table into three.
*/
static const native_int_t table1[] = {
NATIVE_ENTRY_INITIALIZER(SCHAR, signed char, 0, true)
, NATIVE_ENTRY_INITIALIZER(UCHAR, unsigned char, 0, false)
, NATIVE_ENTRY_INITIALIZER(SHORT, short, 0, true)
, NATIVE_ENTRY_INITIALIZER(USHORT, unsigned short, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT, int, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT, unsigned int, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT, int, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT, unsigned int, 0, false)
, NATIVE_ENTRY_INITIALIZER(LONG, long, 0, true)
, NATIVE_ENTRY_INITIALIZER(ULONG, unsigned long, 0, false)
, NATIVE_ENTRY_INITIALIZER(LLONG, long long, 0, true)
, NATIVE_ENTRY_INITIALIZER(ULLONG, unsigned long long, 0, false)
};
static const native_int_t table2[] = {
NATIVE_ENTRY_INITIALIZER(INT8, int8_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT8, uint8_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT_LEAST8, int_least8_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT_LEAST8, uint_least8_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT_FAST8, int_fast8_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT_FAST8, uint_fast8_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT16, int16_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT16, uint16_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT_LEAST16, int_least16_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT_LEAST16, uint_least16_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT_FAST16, int_fast16_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT_FAST16, uint_fast16_t, 0, false)
};
static const native_int_t table3[] = {
NATIVE_ENTRY_INITIALIZER(INT32, int32_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT32, uint32_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT_LEAST32, int_least32_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT_LEAST32, uint_least32_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT_FAST32, int_fast32_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT_FAST32, uint_fast32_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT64, int64_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT64, uint64_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT_LEAST64, int_least64_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT_LEAST64, uint_least64_t, 0, false)
, NATIVE_ENTRY_INITIALIZER(INT_FAST64, int_fast64_t, 0, true)
, NATIVE_ENTRY_INITIALIZER(UINT_FAST64, uint_fast64_t, 0, false)
};
static const native_int_table_t table_table[] = {
{table1, NELMTS(table1)}
, {table2, NELMTS(table2)}
, {table3, NELMTS(table3)}
};
/* clang-format on */
size_t i, j;
H5T_order_t byte_order = get_host_byte_order();
for (i = 0; i < NELMTS(table_table); i++) {
const native_int_t *table = table_table[i].table;
size_t nelmts = table_table[i].nelmts;
/* For each C99 type in `table`, create its H5T_t,
* register a hid_t for the H5T_t, and record the type's
* alignment and hid_t in the variables named by the
* table.
*/
for (j = 0; j < nelmts; j++) {
H5T_t *dt;
if (NULL == (dt = H5T__alloc()))
return FAIL;
dt->shared->state = H5T_STATE_IMMUTABLE;
dt->shared->type = H5T_INTEGER;
dt->shared->size = table[j].size;
dt->shared->u.atomic = table[j].atomic;
dt->shared->u.atomic.order = byte_order;
*table[j].alignmentp = table[j].alignment;
if ((*table[j].hidp = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0)
return FAIL;
}
}
H5T_POINTER_ALIGN_g = TAG_ALIGNMENT(pointer);
H5T_HVL_ALIGN_g = TAG_ALIGNMENT(hvl);
H5T_HOBJREF_ALIGN_g = TAG_ALIGNMENT(hobjref);
H5T_HDSETREGREF_ALIGN_g = TAG_ALIGNMENT(hdsetregref);
H5T_REF_ALIGN_g = TAG_ALIGNMENT(ref);
return SUCCEED;
}

View File

@@ -388,26 +388,22 @@ typedef herr_t (*H5T_operator_t)(H5T_t *dt, void *op_data /*in,out*/);
H5_DLLVAR const unsigned H5O_dtype_ver_bounds[H5F_LIBVER_NBOUNDS];
/*
* Alignment information for native types. A value of N indicates that the
* data must be aligned on an address ADDR such that 0 == ADDR mod N. When
* N=1 no alignment is required; N=0 implies that alignment constraints were
* not calculated. These alignment info is only for H5Tget_native_type.
* These values are used for structure alignment.
* Alignment constraints for HDF5 types. Accessing objects of these
* types with improper alignment invokes C undefined behavior, so the
* library lays out objects with correct alignment, always.
*
* A value of N indicates that the data must be aligned on an address
* ADDR such that 0 == ADDR mod N. When N=1 no alignment is required;
* N=0 implies that alignment constraints were not calculated. These
* values are used for structure alignment.
*
* This alignment info is only for H5Tget_native_type.
*/
H5_DLLVAR size_t H5T_NATIVE_SCHAR_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_SHORT_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_INT_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_LONG_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_LLONG_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_FLOAT_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_DOUBLE_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_POINTER_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_HVL_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_HOBJREF_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_HDSETREGREF_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_REF_COMP_ALIGN_g;
H5_DLLVAR size_t H5T_POINTER_ALIGN_g;
H5_DLLVAR size_t H5T_HVL_ALIGN_g;
H5_DLLVAR size_t H5T_HOBJREF_ALIGN_g;
H5_DLLVAR size_t H5T_HDSETREGREF_ALIGN_g;
H5_DLLVAR size_t H5T_REF_ALIGN_g;
/*
* Alignment information for native types. A value of N indicates that the
@@ -473,6 +469,7 @@ H5FL_EXTERN(H5T_shared_t);
/* Common functions */
H5_DLL herr_t H5T__init_native(void);
H5_DLL herr_t H5T__init_native_internal(void);
H5_DLL H5T_t *H5T__create(H5T_class_t type, size_t size);
H5_DLL H5T_t *H5T__alloc(void);
H5_DLL herr_t H5T__free(H5T_t *dt);

View File

@@ -49,11 +49,6 @@ static const char *FileHeader = "\n\
#include "H5Tpublic.h"
#include "H5Rpublic.h"
/* Disable warning about cast increasing the alignment of the target type,
* that's _exactly_ what this code is probing. -QAK
*/
H5_GCC_CLANG_DIAG_OFF("cast-align")
#if defined(__has_attribute)
#if __has_attribute(no_sanitize_address)
#define HDF_NO_UBSAN __attribute__((no_sanitize_address))
@@ -66,30 +61,6 @@ H5_GCC_CLANG_DIAG_OFF("cast-align")
#define MAXDETECT 64
/* The ALIGNMENT test code may generate the SIGBUS, SIGSEGV, or SIGILL signals.
* We use setjmp/longjmp in the signal handlers for recovery. But setjmp/longjmp
* do not necessary restore the signal blocking status while sigsetjmp/siglongjmp
* do. If sigsetjmp/siglongjmp are not supported, need to use sigprocmask to
* unblock the signal before doing longjmp.
*/
/* Define H5SETJMP/H5LONGJMP depending on if sigsetjmp/siglongjmp are */
/* supported. */
#if defined(H5_HAVE_SIGSETJMP) && defined(H5_HAVE_SIGLONGJMP)
/* Always save blocked signals to be restored by siglongjmp. */
#define H5JMP_BUF sigjmp_buf
#define H5SETJMP(buf) HDsigsetjmp(buf, 1)
#define H5LONGJMP(buf, val) HDsiglongjmp(buf, val)
#define H5HAVE_SIGJMP /* sigsetjmp/siglongjmp are supported. */
#else
#define H5JMP_BUF jmp_buf
#define H5SETJMP(buf) HDsetjmp(buf)
#define H5LONGJMP(buf, val) HDlongjmp(buf, val)
#endif
/* ALIGNMENT and signal-handling status codes */
#define STA_NoALIGNMENT 0x0001 /* No ALIGNMENT Test */
#define STA_NoHandlerVerify 0x0002 /* No signal handler Tests */
/*
* This structure holds information about a type that
* was detected.
@@ -105,27 +76,18 @@ typedef struct detected_t {
unsigned int mpos, msize, imp; /* information about mantissa */
unsigned int epos, esize; /* information about exponent */
unsigned long bias; /* exponent bias for floating pt */
unsigned int align; /* required byte alignment */
unsigned int comp_align; /* alignment for structure */
} detected_t;
/* This structure holds structure alignment for pointers, vlen and reference
* types. */
typedef struct malign_t {
const char * name;
unsigned int comp_align; /* alignment for structure */
} malign_t;
FILE *rawoutstream = NULL;
/* global variables types detection code */
H5_GCC_DIAG_OFF("larger-than=")
static detected_t d_g[MAXDETECT];
H5_GCC_DIAG_ON("larger-than=")
static malign_t m_g[MAXDETECT];
static volatile int nd_g = 0, na_g = 0;
static volatile int nd_g = 0;
static void print_results(int nd, detected_t *d, int na, malign_t *m);
static void print_results(int nd, detected_t *d);
static void iprint(detected_t *);
static int byte_cmp(int, const void *, const void *, const unsigned char *);
static unsigned int bit_cmp(unsigned int, int *, void *, void *, const unsigned char *);
@@ -134,23 +96,8 @@ static unsigned int imp_bit(unsigned int, int *, void *, void *, const unsigned
static unsigned int find_bias(unsigned int, unsigned int, int *, void *);
static void precision(detected_t *);
static void print_header(void);
static void detect_C89_integers(void);
static void detect_C89_floats(void);
static void detect_C99_integers(void);
static void detect_C99_floats(void);
static void detect_C99_integers8(void);
static void detect_C99_integers16(void);
static void detect_C99_integers32(void);
static void detect_C99_integers64(void);
static void detect_alignments(void);
static unsigned int align_g[] = {1, 2, 4, 8, 16};
static int align_status_g = 0; /* ALIGNMENT Signal Status */
static int sigbus_handler_called_g = 0; /* how many times called */
static int sigsegv_handler_called_g = 0; /* how many times called */
static int sigill_handler_called_g = 0; /* how many times called */
static int signal_handler_tested_g = 0; /* how many times tested */
static int verify_signal_handlers(int signum, void (*handler)(int));
static H5JMP_BUF jbuf_g;
/*-------------------------------------------------------------------------
* Function: precision
@@ -163,104 +110,11 @@ static H5JMP_BUF jbuf_g;
static void
precision(detected_t *d)
{
unsigned int n;
if (0 == d->msize) {
/*
* An integer. The permutation can have negative values at the
* beginning or end which represent padding of bytes. We must adjust
* the precision and offset accordingly.
*/
if (d->perm[0] < 0) {
/*
* Lower addresses are padded.
*/
for (n = 0; n < d->size && d->perm[n] < 0; n++)
/*void*/;
d->precision = 8 * (d->size - n);
d->offset = 0;
}
else if (d->perm[d->size - 1] < 0) {
/*
* Higher addresses are padded.
*/
for (n = 0; n < d->size && d->perm[d->size - (n + 1)]; n++)
/*void*/;
d->precision = 8 * (d->size - n);
d->offset = 8 * n;
}
else {
/*
* No padding.
*/
d->precision = 8 * d->size;
d->offset = 0;
}
}
else {
/* A floating point */
d->offset = MIN3(d->mpos, d->epos, d->sign);
d->precision = d->msize + d->esize + 1;
}
/* A floating point */
d->offset = MIN3(d->mpos, d->epos, d->sign);
d->precision = d->msize + d->esize + 1;
}
/*-------------------------------------------------------------------------
* Function: DETECT_I/DETECT_BYTE
*
* Purpose: These macro takes a type like `int' and a base name like
* `nati' and detects the byte order. The VAR is used to
* construct the names of the C variables defined.
*
* DETECT_I is used for types that are larger than one byte,
* DETECT_BYTE is used for types that are exactly one byte.
*
* Return: void
*
*-------------------------------------------------------------------------
*/
#define DETECT_I_BYTE_CORE(TYPE, VAR, INFO, DETECT_TYPE) \
{ \
DETECT_TYPE _v; \
int _i, _j; \
unsigned char *_x; \
\
HDmemset(&INFO, 0, sizeof(INFO)); \
INFO.varname = #VAR; \
INFO.size = sizeof(TYPE); \
\
for (_i = sizeof(DETECT_TYPE), _v = 0; _i > 0; --_i) \
_v = (DETECT_TYPE)((DETECT_TYPE)(_v << 8) + (DETECT_TYPE)_i); \
\
for (_i = 0, _x = (unsigned char *)&_v; _i < (signed)sizeof(DETECT_TYPE); _i++) { \
_j = (*_x++) - 1; \
HDassert(_j < (signed)sizeof(DETECT_TYPE)); \
INFO.perm[_i] = _j; \
} /* end for */ \
\
INFO.sign = ('U' != *(#VAR)); \
precision(&(INFO)); \
ALIGNMENT(TYPE, INFO); \
if (!HDstrcmp(INFO.varname, "SCHAR") || !HDstrcmp(INFO.varname, "SHORT") || \
!HDstrcmp(INFO.varname, "INT") || !HDstrcmp(INFO.varname, "LONG") || \
!HDstrcmp(INFO.varname, "LLONG")) { \
COMP_ALIGNMENT(TYPE, INFO.comp_align); \
} \
}
#define DETECT_BYTE(TYPE, VAR, INFO) \
{ \
HDcompile_assert(sizeof(TYPE) == 1); \
\
DETECT_I_BYTE_CORE(TYPE, VAR, INFO, int) \
}
#define DETECT_I(TYPE, VAR, INFO) \
{ \
HDcompile_assert(sizeof(TYPE) > 1); \
\
DETECT_I_BYTE_CORE(TYPE, VAR, INFO, TYPE) \
}
/*-------------------------------------------------------------------------
* Function: DETECT_F
*
@@ -351,28 +205,12 @@ precision(detected_t *d)
_v1 = (TYPE)1.0L; \
INFO.bias = find_bias(INFO.epos, INFO.esize, INFO.perm, &_v1); \
precision(&(INFO)); \
ALIGNMENT(TYPE, INFO); \
if (!HDstrcmp(INFO.varname, "FLOAT") || !HDstrcmp(INFO.varname, "DOUBLE") || \
!HDstrcmp(INFO.varname, "LDOUBLE")) { \
COMP_ALIGNMENT(TYPE, INFO.comp_align); \
} \
}
/*-------------------------------------------------------------------------
* Function: DETECT_M
*
* Purpose: This macro takes only miscellaneous structures or pointer.
* It constructs the names and decides the alignment in structure.
*
* Return: void
*-------------------------------------------------------------------------
*/
#define DETECT_M(TYPE, VAR, INFO) \
{ \
INFO.name = #VAR; \
COMP_ALIGNMENT(TYPE, INFO.comp_align); \
}
/* Detect alignment for C structure */
#define COMP_ALIGNMENT(TYPE, COMP_ALIGN) \
{ \
@@ -384,140 +222,6 @@ precision(detected_t *d)
COMP_ALIGN = (unsigned int)((char *)(&(s.x)) - (char *)(&s)); \
}
#define ALIGNMENT(TYPE, INFO) \
{ \
char *volatile _buf = NULL; \
TYPE _val = 1, _val2; \
volatile size_t _ano = 0; \
void (*_handler)(int) = HDsignal(SIGBUS, sigbus_handler); \
void (*_handler2)(int) = HDsignal(SIGSEGV, sigsegv_handler); \
void (*_handler3)(int) = HDsignal(SIGILL, sigill_handler); \
\
_buf = (char *)HDmalloc(sizeof(TYPE) + align_g[NELMTS(align_g) - 1]); \
if (H5SETJMP(jbuf_g)) \
_ano++; \
if (_ano < NELMTS(align_g)) { \
*((TYPE *)(_buf + align_g[_ano])) = _val; /*possible SIGBUS or SEGSEGV*/ \
_val2 = *((TYPE *)(_buf + align_g[_ano])); /*possible SIGBUS or SEGSEGV*/ \
/* Cray Check: This section helps detect alignment on Cray's */ \
/* vector machines (like the SV1) which mask off */ \
/* pointer values when pointing to non-word aligned */ \
/* locations with pointers that are supposed to be */ \
/* word aligned. -QAK */ \
HDmemset(_buf, 0xff, sizeof(TYPE) + align_g[NELMTS(align_g) - 1]); \
/*How to handle VAX types?*/ \
if (INFO.perm[0]) /* Big-Endian */ \
HDmemcpy(_buf + align_g[_ano] + (INFO.size - ((INFO.offset + INFO.precision) / 8)), \
((char *)&_val) + (INFO.size - ((INFO.offset + INFO.precision) / 8)), \
(size_t)(INFO.precision / 8)); \
else /* Little-Endian */ \
HDmemcpy(_buf + align_g[_ano] + (INFO.offset / 8), ((char *)&_val) + (INFO.offset / 8), \
(size_t)(INFO.precision / 8)); \
_val2 = *((TYPE *)(_buf + align_g[_ano])); \
H5_GCC_CLANG_DIAG_OFF("float-equal") \
if (_val != _val2) \
H5LONGJMP(jbuf_g, 1); \
H5_GCC_CLANG_DIAG_ON("float-equal") \
/* End Cray Check */ \
(INFO.align) = align_g[_ano]; \
} \
else { \
(INFO.align) = 0; \
fprintf(stderr, "unable to calculate alignment for %s\n", #TYPE); \
} \
HDfree(_buf); \
HDsignal(SIGBUS, _handler); /*restore original handler*/ \
HDsignal(SIGSEGV, _handler2); /*restore original handler*/ \
HDsignal(SIGILL, _handler3); /*restore original handler*/ \
}
/*-------------------------------------------------------------------------
* Function: sigsegv_handler
*
* Purpose: Handler for SIGSEGV. We use signal() instead of sigaction()
* because it's more portable to non-Posix systems. Although
* it's not nearly as nice to work with, it does the job for
* this simple stuff.
*
* Return: Returns via H5LONGJMP to jbuf_g.
*-------------------------------------------------------------------------
*/
static void
sigsegv_handler(int H5_ATTR_UNUSED signo)
{
#if !defined(H5HAVE_SIGJMP) && defined(H5_HAVE_SIGPROCMASK)
/* Use sigprocmask to unblock the signal if sigsetjmp/siglongjmp are not */
/* supported. */
sigset_t set;
HDsigemptyset(&set);
HDsigaddset(&set, SIGSEGV);
HDsigprocmask(SIG_UNBLOCK, &set, NULL);
#endif
sigsegv_handler_called_g++;
HDsignal(SIGSEGV, sigsegv_handler);
H5LONGJMP(jbuf_g, SIGSEGV);
}
/*-------------------------------------------------------------------------
* Function: sigbus_handler
*
* Purpose: Handler for SIGBUS. We use signal() instead of sigaction()
* because it's more portable to non-Posix systems. Although
* it's not nearly as nice to work with, it does the job for
* this simple stuff.
*
* Return: Returns via H5LONGJMP to jbuf_g.
*-------------------------------------------------------------------------
*/
static void
sigbus_handler(int H5_ATTR_UNUSED signo)
{
#if !defined(H5HAVE_SIGJMP) && defined(H5_HAVE_SIGPROCMASK)
/* Use sigprocmask to unblock the signal if sigsetjmp/siglongjmp are not */
/* supported. */
sigset_t set;
HDsigemptyset(&set);
HDsigaddset(&set, SIGBUS);
HDsigprocmask(SIG_UNBLOCK, &set, NULL);
#endif
sigbus_handler_called_g++;
HDsignal(SIGBUS, sigbus_handler);
H5LONGJMP(jbuf_g, SIGBUS);
}
/*-------------------------------------------------------------------------
* Function: sigill_handler
*
* Purpose: Handler for SIGILL. We use signal() instead of sigaction()
* because it's more portable to non-Posix systems. Although
* it's not nearly as nice to work with, it does the job for
* this simple stuff.
*
* Return: Returns via H5LONGJMP to jbuf_g.
*-------------------------------------------------------------------------
*/
static void
sigill_handler(int H5_ATTR_UNUSED signo)
{
#if !defined(H5HAVE_SIGJMP) && defined(H5_HAVE_SIGPROCMASK)
/* Use sigprocmask to unblock the signal if sigsetjmp/siglongjmp are not */
/* supported. */
sigset_t set;
HDsigemptyset(&set);
HDsigaddset(&set, SIGILL);
HDsigprocmask(SIG_UNBLOCK, &set, NULL);
#endif
sigill_handler_called_g++;
HDsignal(SIGILL, sigill_handler);
H5LONGJMP(jbuf_g, SIGILL);
}
/*-------------------------------------------------------------------------
* Function: print_results
*
@@ -527,7 +231,7 @@ sigill_handler(int H5_ATTR_UNUSED signo)
*-------------------------------------------------------------------------
*/
static void
print_results(int nd, detected_t *d, int na, malign_t *misc_align)
print_results(int nd, detected_t *d)
{
int byte_order = 0; /*byte order of data types*/
int i, j;
@@ -645,10 +349,9 @@ H5T__init_native(void)\n\
if(NULL == (dt = H5T__alloc()))\n\
HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, \"datatype allocation failed\")\n\
dt->shared->state = H5T_STATE_IMMUTABLE;\n\
dt->shared->type = H5T_%s;\n\
dt->shared->type = H5T_FLOAT;\n\
dt->shared->size = %d;\n",
d[i].msize ? "FLOAT" : "INTEGER", /*class */
d[i].size); /*size */
d[i].size); /*size */
if (byte_order == -1)
fprintf(rawoutstream, "\
@@ -669,46 +372,36 @@ H5T__init_native(void)\n\
d[i].precision); /*precision */
/*HDassert((d[i].perm[0]>0)==(byte_order>0));*/ /* Double-check that byte-order doesn't change */
if (0 == d[i].msize) {
/* The part unique to fixed point types */
fprintf(rawoutstream, "\
dt->shared->u.atomic.u.i.sign = H5T_SGN_%s;\n",
d[i].sign ? "2" : "NONE");
}
else {
/* The part unique to floating point types */
fprintf(rawoutstream, "\
dt->shared->u.atomic.u.f.sign = %d;\n\
dt->shared->u.atomic.u.f.epos = %d;\n\
dt->shared->u.atomic.u.f.esize = %d;\n\
dt->shared->u.atomic.u.f.ebias = 0x%08lx;\n\
dt->shared->u.atomic.u.f.mpos = %d;\n\
dt->shared->u.atomic.u.f.msize = %d;\n\
dt->shared->u.atomic.u.f.norm = H5T_NORM_%s;\n\
dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;\n",
d[i].sign, /*sign location */
d[i].epos, /*exponent loc */
d[i].esize, /*exponent size */
(unsigned long)(d[i].bias), /*exponent bias */
d[i].mpos, /*mantissa loc */
d[i].msize, /*mantissa size */
d[i].imp ? "IMPLIED" : "NONE"); /*normalization */
}
/* The part unique to floating point types */
fprintf(rawoutstream, "\
dt->shared->u.atomic.u.f.sign = %d;\n\
dt->shared->u.atomic.u.f.epos = %d;\n\
dt->shared->u.atomic.u.f.esize = %d;\n\
dt->shared->u.atomic.u.f.ebias = 0x%08lx;\n\
dt->shared->u.atomic.u.f.mpos = %d;\n\
dt->shared->u.atomic.u.f.msize = %d;\n\
dt->shared->u.atomic.u.f.norm = H5T_NORM_%s;\n\
dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;\n",
d[i].sign, /*sign location */
d[i].epos, /*exponent loc */
d[i].esize, /*exponent size */
(unsigned long)(d[i].bias), /*exponent bias */
d[i].mpos, /*mantissa loc */
d[i].msize, /*mantissa size */
d[i].imp ? "IMPLIED" : "NONE"); /*normalization */
/* Register the type */
fprintf(rawoutstream, "\
if((H5T_NATIVE_%s_g = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0)\n\
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \"can't register ID for built-in datatype\")\n",
d[i].varname);
fprintf(rawoutstream, " H5T_NATIVE_%s_ALIGN_g = %lu;\n", d[i].varname,
(unsigned long)(d[i].align));
/* Variables for alignment of compound datatype */
if (!HDstrcmp(d[i].varname, "SCHAR") || !HDstrcmp(d[i].varname, "SHORT") ||
!HDstrcmp(d[i].varname, "INT") || !HDstrcmp(d[i].varname, "LONG") ||
!HDstrcmp(d[i].varname, "LLONG") || !HDstrcmp(d[i].varname, "FLOAT") ||
!HDstrcmp(d[i].varname, "DOUBLE") || !HDstrcmp(d[i].varname, "LDOUBLE")) {
fprintf(rawoutstream, " H5T_NATIVE_%s_COMP_ALIGN_g = %lu;\n", d[i].varname,
fprintf(rawoutstream, " H5T_NATIVE_%s_ALIGN_g = %lu;\n", d[i].varname,
(unsigned long)(d[i].comp_align));
}
}
@@ -727,12 +420,6 @@ H5T__init_native(void)\n\
"BE");
}
/* Structure alignment for pointers, vlen and reference types */
fprintf(rawoutstream, "\n /* Structure alignment for pointers, vlen and reference types */\n");
for (j = 0; j < na; j++)
fprintf(rawoutstream, " H5T_%s_COMP_ALIGN_g = %lu;\n", misc_align[j].name,
(unsigned long)(misc_align[j].comp_align));
fprintf(rawoutstream, "\
\n\
done:\n\
@@ -745,42 +432,6 @@ done:\n\
\n\
FUNC_LEAVE_NOAPI(ret_value);\n} /* end H5T__init_native() */\n");
/* Print the ALIGNMENT and signal-handling status as comments */
fprintf(rawoutstream, "\n"
"/****************************************/\n"
"/* ALIGNMENT and signal-handling status */\n"
"/****************************************/\n");
if (align_status_g & STA_NoALIGNMENT)
fprintf(rawoutstream, "/* ALIGNAMENT test is not available */\n");
if (align_status_g & STA_NoHandlerVerify)
fprintf(rawoutstream, "/* Signal handlers verify test is not available */\n");
/* The following is available in H5pubconf.h. Printing them here for */
/* convenience. */
#ifdef H5_HAVE_SIGSETJMP
fprintf(rawoutstream, "/* sigsetjmp() support: yes */\n");
#else
fprintf(rawoutstream, "/* sigsetjmp() support: no */\n");
#endif
#ifdef H5_HAVE_SIGLONGJMP
fprintf(rawoutstream, "/* siglongjmp() support: yes */\n");
#else
fprintf(rawoutstream, "/* siglongjmp() support: no */\n");
#endif
#ifdef H5_HAVE_SIGPROCMASK
fprintf(rawoutstream, "/* sigprocmask() support: yes */\n");
#else
fprintf(rawoutstream, "/* sigprocmask() support: no */\n");
#endif
/* Print the statistics of signal handlers called for debugging */
fprintf(rawoutstream, "\n"
"/******************************/\n"
"/* signal handlers statistics */\n"
"/******************************/\n");
fprintf(rawoutstream, "/* signal_handlers tested: %d times */\n", signal_handler_tested_g);
fprintf(rawoutstream, "/* sigbus_handler called: %d times */\n", sigbus_handler_called_g);
fprintf(rawoutstream, "/* sigsegv_handler called: %d times */\n", sigsegv_handler_called_g);
fprintf(rawoutstream, "/* sigill_handler called: %d times */\n", sigill_handler_called_g);
} /* end print_results() */
/*-------------------------------------------------------------------------
@@ -820,7 +471,7 @@ iprint(detected_t *d)
unsigned int j;
for (j = 8; j > 0; --j) {
if (k == d->sign && d->msize) {
if (k == d->sign) {
HDfputc('S', rawoutstream);
}
else if (k >= d->epos && k < d->epos + d->esize) {
@@ -829,14 +480,8 @@ iprint(detected_t *d)
else if (k >= d->mpos && k < d->mpos + d->msize) {
HDfputc('M', rawoutstream);
}
else if (d->msize) {
HDfputc('?', rawoutstream); /*unknown floating point bit */
}
else if (d->sign) {
HDfputc('I', rawoutstream);
}
else {
HDfputc('U', rawoutstream);
HDfputc('?', rawoutstream); /*unknown floating point bit */
}
--k;
}
@@ -853,22 +498,7 @@ iprint(detected_t *d)
/*
* Is there an implicit bit in the mantissa.
*/
if (d->msize) {
fprintf(rawoutstream, " * Implicit bit? %s\n", d->imp ? "yes" : "no");
}
/*
* Alignment
*/
if (0 == d->align) {
fprintf(rawoutstream, " * Alignment: NOT CALCULATED\n");
}
else if (1 == d->align) {
fprintf(rawoutstream, " * Alignment: none\n");
}
else {
fprintf(rawoutstream, " * Alignment: %lu\n", (unsigned long)(d->align));
}
fprintf(rawoutstream, " * Implicit bit? %s\n", d->imp ? "yes" : "no");
}
/*-------------------------------------------------------------------------
@@ -1221,35 +851,6 @@ bit.\n";
fprintf(rawoutstream, "\n */\n\n");
}
/*-------------------------------------------------------------------------
* Function: detect_C89_integers
*
* Purpose: Detect C89 integer types
*
* Return: void
*-------------------------------------------------------------------------
*/
static void HDF_NO_UBSAN
detect_C89_integers(void)
{
DETECT_BYTE(signed char, SCHAR, d_g[nd_g]);
nd_g++;
DETECT_BYTE(unsigned char, UCHAR, d_g[nd_g]);
nd_g++;
DETECT_I(short, SHORT, d_g[nd_g]);
nd_g++;
DETECT_I(unsigned short, USHORT, d_g[nd_g]);
nd_g++;
DETECT_I(int, INT, d_g[nd_g]);
nd_g++;
DETECT_I(unsigned int, UINT, d_g[nd_g]);
nd_g++;
DETECT_I(long, LONG, d_g[nd_g]);
nd_g++;
DETECT_I(unsigned long, ULONG, d_g[nd_g]);
nd_g++;
}
/*-------------------------------------------------------------------------
* Function: detect_C89_floats
*
@@ -1267,131 +868,6 @@ detect_C89_floats(void)
nd_g++;
}
/*-------------------------------------------------------------------------
* Function: detect_C99_integers8
*
* Purpose: Detect C99 8 bit integer types
*
* Return: void
*-------------------------------------------------------------------------
*/
static void HDF_NO_UBSAN
detect_C99_integers8(void)
{
DETECT_BYTE(int8_t, INT8, d_g[nd_g]);
nd_g++;
DETECT_BYTE(uint8_t, UINT8, d_g[nd_g]);
nd_g++;
DETECT_BYTE(int_least8_t, INT_LEAST8, d_g[nd_g]);
nd_g++;
DETECT_BYTE(uint_least8_t, UINT_LEAST8, d_g[nd_g]);
nd_g++;
DETECT_BYTE(int_fast8_t, INT_FAST8, d_g[nd_g]);
nd_g++;
DETECT_BYTE(uint_fast8_t, UINT_FAST8, d_g[nd_g]);
nd_g++;
}
/*-------------------------------------------------------------------------
* Function: detect_C99_integers16
*
* Purpose: Detect C99 16 bit integer types
*
* Return: void
*-------------------------------------------------------------------------
*/
static void HDF_NO_UBSAN
detect_C99_integers16(void)
{
DETECT_I(int16_t, INT16, d_g[nd_g]);
nd_g++;
DETECT_I(uint16_t, UINT16, d_g[nd_g]);
nd_g++;
DETECT_I(int_least16_t, INT_LEAST16, d_g[nd_g]);
nd_g++;
DETECT_I(uint_least16_t, UINT_LEAST16, d_g[nd_g]);
nd_g++;
DETECT_I(int_fast16_t, INT_FAST16, d_g[nd_g]);
nd_g++;
DETECT_I(uint_fast16_t, UINT_FAST16, d_g[nd_g]);
nd_g++;
}
/*-------------------------------------------------------------------------
* Function: detect_C99_integers32
*
* Purpose: Detect C99 32 bit integer types
*
* Return: void
*-------------------------------------------------------------------------
*/
static void HDF_NO_UBSAN
detect_C99_integers32(void)
{
DETECT_I(int32_t, INT32, d_g[nd_g]);
nd_g++;
DETECT_I(uint32_t, UINT32, d_g[nd_g]);
nd_g++;
DETECT_I(int_least32_t, INT_LEAST32, d_g[nd_g]);
nd_g++;
DETECT_I(uint_least32_t, UINT_LEAST32, d_g[nd_g]);
nd_g++;
DETECT_I(int_fast32_t, INT_FAST32, d_g[nd_g]);
nd_g++;
DETECT_I(uint_fast32_t, UINT_FAST32, d_g[nd_g]);
nd_g++;
}
/*-------------------------------------------------------------------------
* Function: detect_C99_integers64
*
* Purpose: Detect C99 64 bit integer types
*
* Return: void
*
*-------------------------------------------------------------------------
*/
static void HDF_NO_UBSAN
detect_C99_integers64(void)
{
DETECT_I(int64_t, INT64, d_g[nd_g]);
nd_g++;
DETECT_I(uint64_t, UINT64, d_g[nd_g]);
nd_g++;
DETECT_I(int_least64_t, INT_LEAST64, d_g[nd_g]);
nd_g++;
DETECT_I(uint_least64_t, UINT_LEAST64, d_g[nd_g]);
nd_g++;
DETECT_I(int_fast64_t, INT_FAST64, d_g[nd_g]);
nd_g++;
DETECT_I(uint_fast64_t, UINT_FAST64, d_g[nd_g]);
nd_g++;
DETECT_I(long long, LLONG, d_g[nd_g]);
nd_g++;
DETECT_I(unsigned long long, ULLONG, d_g[nd_g]);
nd_g++;
}
/*-------------------------------------------------------------------------
* Function: detect_C99_integers
*
* Purpose: Detect C99 integer types
*
* Return: void
*-------------------------------------------------------------------------
*/
static void HDF_NO_UBSAN
detect_C99_integers(void)
{
/* break it down to more subroutines so that each module subroutine */
/* is smaller and takes less time to compile with optimization on. */
detect_C99_integers8();
detect_C99_integers16();
detect_C99_integers32();
detect_C99_integers64();
}
/*-------------------------------------------------------------------------
* Function: detect_C99_floats
*
@@ -1418,87 +894,6 @@ detect_C99_floats(void)
#endif
}
/*-------------------------------------------------------------------------
* Function: detect_alignments
*
* Purpose: Detect structure alignments
*
* Return: void
*-------------------------------------------------------------------------
*/
static void HDF_NO_UBSAN
detect_alignments(void)
{
/* Detect structure alignment for pointers, vlen and reference types */
DETECT_M(void *, POINTER, m_g[na_g]);
na_g++;
DETECT_M(hvl_t, HVL, m_g[na_g]);
na_g++;
DETECT_M(hobj_ref_t, HOBJREF, m_g[na_g]);
na_g++;
DETECT_M(hdset_reg_ref_t, HDSETREGREF, m_g[na_g]);
na_g++;
DETECT_M(H5R_ref_t, REF, m_g[na_g]);
na_g++;
}
/* Verify the signal handler for signal signum works correctly multiple times.
* One possible cause of failure is that the signal handling is blocked or
* changed to SIG_DFL after H5LONGJMP.
* Return 0 for success, -1 for failure.
*/
static int
verify_signal_handlers(int signum, void (*handler)(int))
{
#if defined(__has_feature) /* Clang */
#if __has_feature(address_sanitizer) || __has_feature(thread_sanitizer)
/* Under the address and thread sanitizers, don't raise any signals. */
return 0;
#endif
#elif defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__) /* GCC */
return 0;
#endif
void (*save_handler)(int) = HDsignal(signum, handler);
volatile int i, val;
int ntries = 5;
volatile int nfailures = 0;
volatile int nsuccesses = 0;
for (i = 0; i < ntries; i++) {
val = H5SETJMP(jbuf_g);
if (val == 0) {
/* send self the signal to trigger the handler */
signal_handler_tested_g++;
HDraise(signum);
/* Should not reach here. Record error. */
nfailures++;
}
else {
if (val == signum) {
/* return from signum handler. Record a success. */
nsuccesses++;
}
else {
fprintf(stderr, "Unknown return value (%d) from H5SETJMP", val);
nfailures++;
}
}
}
/* restore save handler, check results and report failures */
HDsignal(signum, save_handler);
if (nfailures > 0 || nsuccesses != ntries) {
fprintf(stderr,
"verify_signal_handlers for signal %d did %d tries. "
"Found %d failures and %d successes\n",
signum, ntries, nfailures, nsuccesses);
return -1;
}
else {
/* all succeeded */
return 0;
}
}
/*-------------------------------------------------------------------------
* Function: main
*
@@ -1527,35 +922,15 @@ main(int argc, char *argv[])
if (!rawoutstream)
rawoutstream = stdout;
/* verify the SIGBUS and SIGSEGV handlers work properly */
if (verify_signal_handlers(SIGBUS, sigbus_handler) != 0) {
fprintf(stderr, "Signal handler %s for signal %d failed\n", "sigbus_handler", SIGBUS);
}
if (verify_signal_handlers(SIGSEGV, sigsegv_handler) != 0) {
fprintf(stderr, "Signal handler %s for signal %d failed\n", "sigsegv_handler", SIGSEGV);
}
if (verify_signal_handlers(SIGILL, sigill_handler) != 0) {
fprintf(stderr, "Signal handler %s for signal %d failed\n", "sigill_handler", SIGILL);
}
print_header();
/* C89 integer types */
detect_C89_integers();
/* C99 integer types */
detect_C99_integers();
/* C89 floating point types */
detect_C89_floats();
/* C99 floating point types */
detect_C99_floats();
/* Detect structure alignment */
detect_alignments();
print_results(nd_g, d_g, na_g, m_g);
print_results(nd_g, d_g);
if (rawoutstream && rawoutstream != stdout) {
if (HDfclose(rawoutstream))
@@ -1566,5 +941,3 @@ main(int argc, char *argv[])
return EXIT_SUCCESS;
}
H5_GCC_CLANG_DIAG_ON("cast-align")