-
-
Notifications
You must be signed in to change notification settings - Fork 281
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
Fix two assertion failures in hyperslab code #5355
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2827,9 +2827,11 @@ H5S__hyper_new_span_info(unsigned rank) | |
FUNC_ENTER_PACKAGE | ||
|
||
/* Sanity check */ | ||
assert(rank > 0); | ||
assert(rank <= H5S_MAX_RANK); | ||
|
||
if (rank == 0) | ||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, NULL, "dataspace has invalid extent"); | ||
|
||
/* Allocate a new span info node */ | ||
if (NULL == (ret_value = (H5S_hyper_span_info_t *)H5FL_ARR_CALLOC(hbounds_t, rank * 2))) | ||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span info"); | ||
|
@@ -3204,7 +3206,7 @@ H5S__hyper_free_span(H5S_hyper_span_t *span) | |
static herr_t | ||
H5S__hyper_copy(H5S_t *dst, const H5S_t *src, bool share_selection) | ||
{ | ||
H5S_hyper_sel_t *dst_hslab; /* Pointer to destination hyperslab info */ | ||
H5S_hyper_sel_t *dst_hslab = NULL; /* Pointer to destination hyperslab info */ | ||
const H5S_hyper_sel_t *src_hslab; /* Pointer to source hyperslab info */ | ||
herr_t ret_value = SUCCEED; /* Return value */ | ||
|
||
|
@@ -3215,11 +3217,11 @@ H5S__hyper_copy(H5S_t *dst, const H5S_t *src, bool share_selection) | |
assert(dst); | ||
|
||
/* Allocate space for the hyperslab selection information */ | ||
if (NULL == (dst->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) | ||
if (NULL == (dst_hslab = H5FL_MALLOC(H5S_hyper_sel_t))) | ||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info"); | ||
dst_hslab->span_lst = NULL; | ||
|
||
/* Set temporary pointers */ | ||
dst_hslab = dst->select.sel_info.hslab; | ||
src_hslab = src->select.sel_info.hslab; | ||
|
||
/* Copy the hyperslab information */ | ||
|
@@ -3229,25 +3231,38 @@ H5S__hyper_copy(H5S_t *dst, const H5S_t *src, bool share_selection) | |
|
||
/* Check if there is hyperslab span information to copy */ | ||
/* (Regular hyperslab information is copied with the selection structure) */ | ||
if (src->select.sel_info.hslab->span_lst != NULL) { | ||
if (src_hslab->span_lst != NULL) { | ||
if (share_selection) { | ||
/* Share the source's span tree by incrementing the reference count on it */ | ||
dst->select.sel_info.hslab->span_lst = src->select.sel_info.hslab->span_lst; | ||
dst->select.sel_info.hslab->span_lst->count++; | ||
dst_hslab->span_lst = src_hslab->span_lst; | ||
dst_hslab->span_lst->count++; | ||
} /* end if */ | ||
else | ||
else { | ||
/* Copy the hyperslab span information */ | ||
dst->select.sel_info.hslab->span_lst = | ||
H5S__hyper_copy_span(src->select.sel_info.hslab->span_lst, src->extent.rank); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Code wasn't previously checking for errors here, which would hide problems when trying to copy a dataspace with an extent of 0 dims. |
||
dst_hslab->span_lst = H5S__hyper_copy_span(src_hslab->span_lst, src->extent.rank); | ||
if (NULL == dst_hslab->span_lst) | ||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy hyperslab span information"); | ||
} | ||
} /* end if */ | ||
else | ||
dst->select.sel_info.hslab->span_lst = NULL; | ||
dst_hslab->span_lst = NULL; | ||
|
||
/* Copy the unlimited dimension info */ | ||
dst_hslab->unlim_dim = src_hslab->unlim_dim; | ||
dst_hslab->num_elem_non_unlim = src_hslab->num_elem_non_unlim; | ||
|
||
dst->select.sel_info.hslab = dst_hslab; | ||
|
||
done: | ||
if (ret_value < 0) { | ||
if (dst_hslab) { | ||
if (dst_hslab->span_lst && H5S__hyper_free_span_info(dst_hslab->span_lst) < 0) | ||
HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free hyperslab span information"); | ||
|
||
H5FL_FREE(H5S_hyper_sel_t, dst_hslab); | ||
} | ||
} | ||
|
||
FUNC_LEAVE_NOAPI(ret_value) | ||
} /* end H5S__hyper_copy() */ | ||
|
||
|
@@ -8603,12 +8618,14 @@ H5S__hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride | |
FUNC_ENTER_PACKAGE | ||
|
||
/* Check args */ | ||
assert(rank > 0); | ||
assert(start); | ||
assert(stride); | ||
assert(count); | ||
assert(block); | ||
|
||
if (rank == 0) | ||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, NULL, "dataspace has invalid extent"); | ||
|
||
/* Start creating spans in fastest changing dimension */ | ||
for (i = (int)(rank - 1); i >= 0; i--) { | ||
hsize_t curr_low, curr_high; /* Current low & high values */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -218,26 +218,39 @@ H5Sselect_copy(hid_t dst_id, hid_t src_id) | |
herr_t | ||
H5S_select_copy(H5S_t *dst, const H5S_t *src, bool share_selection) | ||
{ | ||
herr_t ret_value = FAIL; /* Return value */ | ||
H5S_t tmp_space; | ||
bool copied_space = false; | ||
herr_t ret_value = FAIL; /* Return value */ | ||
|
||
FUNC_ENTER_NOAPI(FAIL) | ||
|
||
/* Check args */ | ||
assert(dst); | ||
assert(src); | ||
|
||
/* Release the current selection */ | ||
if (H5S_SELECT_RELEASE(dst) < 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Part of this PR was fixing |
||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection"); | ||
tmp_space = *dst; | ||
|
||
/* Copy regular fields */ | ||
dst->select = src->select; | ||
tmp_space.select = src->select; | ||
|
||
/* Perform correct type of copy based on the type of selection */ | ||
if ((ret_value = (*src->select.type->copy)(dst, src, share_selection)) < 0) | ||
if ((ret_value = (*src->select.type->copy)(&tmp_space, src, share_selection)) < 0) | ||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection specific information"); | ||
copied_space = true; | ||
|
||
/* Release the current selection */ | ||
if (H5S_SELECT_RELEASE(dst) < 0) | ||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection"); | ||
|
||
*dst = tmp_space; | ||
|
||
done: | ||
|
||
if (ret_value < 0) { | ||
if (copied_space && H5S_SELECT_RELEASE(&tmp_space) < 0) | ||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection"); | ||
} | ||
|
||
FUNC_LEAVE_NOAPI(ret_value) | ||
} /* end H5S_select_copy() */ | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code here and below was directly manipulating the destination dataspace, which could leave things in a bad state if failure occurs. This function had to be reworked to use the local
dst_hslab
and only manipulate the destination dataspace after things have succeeded.