-
Notifications
You must be signed in to change notification settings - Fork 154
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
Allow xcalloc() to return NULL when size is 0 for portability #3452
base: main
Are you sure you want to change the base?
Allow xcalloc() to return NULL when size is 0 for portability #3452
Conversation
This doesn't look correct to me, from
(typical man page confusing text but)
Also, MRuby calloc can return NULL on error, if e.g. So there is at least one MRuby issue which is it should set errno if it returns NULL for an error. In terms of what the caller can do about this poorly-specified behavior of calloc() I think the simplest/straightforward ways are:
if (capacity) {
list->ids = xcalloc(capacity, sizeof(pm_constant_id_t));
if (list->ids == NULL) abort();
} else {
list->ids = NULL;
}
|
528bd3d
to
d544425
Compare
@eregon Thank you very much. I agree with the former option. |
According to the calloc(3) man page, when nmemb or size is 0, `calloc()` can either return NULL or a unique pointer that can be passed to `free()`. While gcc and clang typically return a unique pointer, mruby's `mrb_calloc()` returns NULL in this case. Since `pm_constant_pool_init()` is commonly called with capacity=0 during normal operation of Prism, explicitly handle this case by setting `list->ids` to NULL when capacity is 0. This approach is portable across different calloc implementations and avoids potential issues with mruby's allocation behavior. This maintains compatibility with `free()` and `realloc()`, as passing NULL pointers to these functions is explicitly allowed by their specifications.
d544425
to
1c32252
Compare
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.
LGTM
I wonder if other places also need similar handling. I'll let @kddnewton (or another Prism maintainer) review/merge. |
https://github.com/ruby/prism/blob/v1.3.0/src/prism.c#L766-L767 But I'm also wondering if it's ok that, for example, the below code allows NULL: |
According to the calloc(3) man page, when nmemb or size is 0,
calloc()
can either return NULL or a unique pointer that can be passed to free(): https://manpages.org/calloc/3While gcc (13.3.0) and clang (15.0.7), in my environment, return a unique pointer in this case, mruby's
mrb_calloc
returns NULL.See https://github.com/mruby/mruby/blob/3.3.0/src/gc.c#L253
Since
pm_constant_pool_init()
is commonly called with capacity=0 during normal operation of Prism,xcalloc()
needs to handle NULL returns to integrate with mruby.Per free()'s and realloc()'s specifications, passing a NULL pointer is a valid operation, so this change should be safe.