Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert some H5MM calls to standard C equivalents #2382

Merged
merged 16 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 0 additions & 88 deletions src/H5MM.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,63 +54,6 @@
/* Local Variables */
/*******************/

/*-------------------------------------------------------------------------
* Function: H5MM_malloc
*
* Purpose: Similar to the C89 version of malloc().
*
* On size of 0, we return a NULL pointer instead of the
* standard-allowed 'special' pointer since that's more
* difficult to check as a return value. This is still
* considered an error condition since allocations of zero
* bytes usually indicate problems.
*
* Return: Success: Pointer to new memory
* Failure: NULL
*-------------------------------------------------------------------------
*/
void *
H5MM_malloc(size_t size)
{
void *ret_value = NULL;

/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR

ret_value = HDmalloc(size);

FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_malloc() */

/*-------------------------------------------------------------------------
* Function: H5MM_calloc
*
* Purpose: Similar to the C89 version of calloc(), except this
* routine just takes a 'size' parameter.
*
* On size of 0, we return a NULL pointer instead of the
* standard-allowed 'special' pointer since that's more
* difficult to check as a return value. This is still
* considered an error condition since allocations of zero
* bytes usually indicate problems.
*
* Return: Success: Pointer to new memory
* Failure: NULL
*-------------------------------------------------------------------------
*/
void *
H5MM_calloc(size_t size)
{
void *ret_value = NULL;

/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR

ret_value = HDcalloc(1, size);

FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_calloc() */

/*-------------------------------------------------------------------------
* Function: H5MM_realloc
*
Expand Down Expand Up @@ -282,34 +225,3 @@ H5MM_xfree_const(const void *mem)

FUNC_LEAVE_NOAPI(NULL)
} /* end H5MM_xfree_const() */

/*-------------------------------------------------------------------------
* Function: H5MM_memcpy
*
* Purpose: Like memcpy(3) but with sanity checks on the parameters,
* particularly buffer overlap.
*
* Return: Success: pointer to dest
* Failure: NULL
*-------------------------------------------------------------------------
*/
void *
H5MM_memcpy(void *dest, const void *src, size_t n)
{
void *ret = NULL;

/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR

HDassert(dest);
HDassert(src);

/* Check for buffer overlap */
HDassert((char *)dest >= (const char *)src + n || (const char *)src >= (char *)dest + n);

/* Copy */
ret = HDmemcpy(dest, src, n);

FUNC_LEAVE_NOAPI(ret)

} /* end H5MM_memcpy() */
15 changes: 11 additions & 4 deletions src/H5MMprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,26 @@
/* Private headers needed by this file */
#include "H5private.h"

#define H5MM_free(Z) HDfree(Z)
#define H5MM_calloc(Z) HDcalloc(1, Z)
#define H5MM_free(Z) HDfree(Z)
#define H5MM_malloc(Z) HDmalloc(Z)
/* The void * casts are required to avoid tripping over undefined behavior if
* we are copying to/from poorly aliased pointers. As an example, this can
* happen in the type conversion code if a mis-aligned user buffer is passed
* to H5Tconvert and then cast to a type that assumes alignment. The casts
* will prevent the compiler from doing things like using SSE for the
* memcpy, which has strong alignment constraints.
*/
#define H5MM_memcpy(D, S, N) HDmemcpy((void *)D, (void *)S, N)

/*
* Library prototypes...
*/
H5_DLL void *H5MM_malloc(size_t size) H5_ATTR_MALLOC;
H5_DLL void *H5MM_calloc(size_t size) H5_ATTR_MALLOC;
H5_DLL void *H5MM_realloc(void *mem, size_t size);
H5_DLL char *H5MM_xstrdup(const char *s);
H5_DLL char *H5MM_strdup(const char *s);
H5_DLL char *H5MM_strndup(const char *s, size_t n);
H5_DLL void *H5MM_xfree(void *mem);
H5_DLL void *H5MM_xfree_const(const void *mem);
H5_DLL void *H5MM_memcpy(void *dest, const void *src, size_t n);

#endif /* H5MMprivate_H */
24 changes: 22 additions & 2 deletions src/H5Tconv.c
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,17 @@ done:
/* Macro defining action on source data which needs to be aligned (before main action) */
#define H5T_CONV_LOOP_PRE_SALIGN(ST) \
{ \
H5MM_memcpy(&src_aligned, src, sizeof(ST)); \
/* The uint8_t * cast is required to avoid tripping over undefined behavior. \
* \
* The typed pointer arrives via a void pointer, which may have any alignement. \
* We then cast it to a pointer to a type that is assumed to be aligned, which \
* is undefined behavior (section 6.3.2.3 paragraph 7 of the C99 standard). \
* In the past this hasn't caused many problems, but in some cases (e.g. \
* converting long doubles on macOS), an optimizing compiler might do the \
* wrong thing (in the macOS case, the conversion uses SSE, which has stricter \
* requirements about alignment). \
*/ \
H5MM_memcpy(&src_aligned, (uint8_t *)src, sizeof(ST)); \
derobins marked this conversation as resolved.
Show resolved Hide resolved
}

/* Macro defining action on source data which doesn't need to be aligned (before main action) */
Expand Down Expand Up @@ -919,7 +929,17 @@ done:
/* Macro defining action on destination data which needs to be aligned (after main action) */
#define H5T_CONV_LOOP_POST_DALIGN(DT) \
{ \
H5MM_memcpy(dst, &dst_aligned, sizeof(DT)); \
/* The uint8_t * cast is required to avoid tripping over undefined behavior. \
* \
* The typed pointer arrives via a void pointer, which may have any alignement. \
* We then cast it to a pointer to a type that is assumed to be aligned, which \
* is undefined behavior (section 6.3.2.3 paragraph 7 of the C99 standard). \
* In the past this hasn't caused many problems, but in some cases (e.g. \
* converting long doubles on macOS), an optimizing compiler might do the \
* wrong thing (in the macOS case, the conversion uses SSE, which has stricter \
* requirements about alignment). \
*/ \
H5MM_memcpy((uint8_t *)dst, &dst_aligned, sizeof(DT)); \
}

/* Macro defining action on destination data which doesn't need to be aligned (after main action) */
Expand Down