diff options
| author | Xing Xue <xingxue@outlook.com> | 2019-06-25 15:08:28 +0000 |
|---|---|---|
| committer | Xing Xue <xingxue@outlook.com> | 2019-06-25 15:08:28 +0000 |
| commit | ece53d0ae50a97e42bf99180ab4344352cea2d04 (patch) | |
| tree | 7deb2248fe9c0b3f7e6cb8763320d4405f1e443f /llvm | |
| parent | 36c23cad151ade2ce1350c955ea7fd0ea9dcc674 (diff) | |
| download | bcm5719-llvm-ece53d0ae50a97e42bf99180ab4344352cea2d04.tar.gz bcm5719-llvm-ece53d0ae50a97e42bf99180ab4344352cea2d04.zip | |
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
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Support/MemAlloc.h | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/include/llvm/Support/MemAlloc.h b/llvm/include/llvm/Support/MemAlloc.h index ed076ffa52d..0e5869141fd 100644 --- a/llvm/include/llvm/Support/MemAlloc.h +++ b/llvm/include/llvm/Support/MemAlloc.h @@ -24,23 +24,41 @@ namespace llvm { LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_malloc(size_t Sz) { void *Result = std::malloc(Sz); - if (Result == nullptr) + if (Result == nullptr) { + // It is implementation-defined whether allocation occurs if the space + // requested is zero (ISO/IEC 9899:2018 7.22.3). Retry, requesting + // non-zero, if the space requested was zero. + if (Sz == 0) + return safe_malloc(1); report_bad_alloc_error("Allocation failed"); + } return Result; } LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_calloc(size_t Count, size_t Sz) { void *Result = std::calloc(Count, Sz); - if (Result == nullptr) + if (Result == nullptr) { + // It is implementation-defined whether allocation occurs if the space + // requested is zero (ISO/IEC 9899:2018 7.22.3). Retry, requesting + // non-zero, if the space requested was zero. + if (Count == 0 || Sz == 0) + return safe_malloc(1); report_bad_alloc_error("Allocation failed"); + } return Result; } LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_realloc(void *Ptr, size_t Sz) { void *Result = std::realloc(Ptr, Sz); - if (Result == nullptr) + if (Result == nullptr) { + // It is implementation-defined whether allocation occurs if the space + // requested is zero (ISO/IEC 9899:2018 7.22.3). Retry, requesting + // non-zero, if the space requested was zero. + if (Sz == 0) + return safe_malloc(1); report_bad_alloc_error("Allocation failed"); + } return Result; } |

