Skip to content

Commit ece53d0

Browse files
committedJun 25, 2019
Improve zero-size allocation with safe_malloc, etc.
Summary: The current implementations of the memory allocation functions mistake a nullptr returned from std::malloc, std::calloc, or std::realloc as a failure. The behaviour for each of std::malloc, std::calloc, and std::realloc when the size is 0 is implementation defined (ISO/IEC 9899:2018 7.22.3), and may return a nullptr. This patch checks if space requested is zero when a nullptr is returned, retry requesting non-zero if it is. Authored By: andusy Reviewers: hubert.reinterpretcast, xingxue, jasonliu Reviewed By: hubert.reinterpretcast, xingxue, abrachet Subscribers: abrachet, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63668 llvm-svn: 364322
1 parent 36c23ca commit ece53d0

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed
 

‎llvm/include/llvm/Support/MemAlloc.h

+21-3
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,41 @@ namespace llvm {
2424

2525
LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_malloc(size_t Sz) {
2626
void *Result = std::malloc(Sz);
27-
if (Result == nullptr)
27+
if (Result == nullptr) {
28+
// It is implementation-defined whether allocation occurs if the space
29+
// requested is zero (ISO/IEC 9899:2018 7.22.3). Retry, requesting
30+
// non-zero, if the space requested was zero.
31+
if (Sz == 0)
32+
return safe_malloc(1);
2833
report_bad_alloc_error("Allocation failed");
34+
}
2935
return Result;
3036
}
3137

3238
LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_calloc(size_t Count,
3339
size_t Sz) {
3440
void *Result = std::calloc(Count, Sz);
35-
if (Result == nullptr)
41+
if (Result == nullptr) {
42+
// It is implementation-defined whether allocation occurs if the space
43+
// requested is zero (ISO/IEC 9899:2018 7.22.3). Retry, requesting
44+
// non-zero, if the space requested was zero.
45+
if (Count == 0 || Sz == 0)
46+
return safe_malloc(1);
3647
report_bad_alloc_error("Allocation failed");
48+
}
3749
return Result;
3850
}
3951

4052
LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_realloc(void *Ptr, size_t Sz) {
4153
void *Result = std::realloc(Ptr, Sz);
42-
if (Result == nullptr)
54+
if (Result == nullptr) {
55+
// It is implementation-defined whether allocation occurs if the space
56+
// requested is zero (ISO/IEC 9899:2018 7.22.3). Retry, requesting
57+
// non-zero, if the space requested was zero.
58+
if (Sz == 0)
59+
return safe_malloc(1);
4360
report_bad_alloc_error("Allocation failed");
61+
}
4462
return Result;
4563
}
4664

0 commit comments

Comments
 (0)
Please sign in to comment.