summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorXing Xue <xingxue@outlook.com>2019-06-25 15:08:28 +0000
committerXing Xue <xingxue@outlook.com>2019-06-25 15:08:28 +0000
commitece53d0ae50a97e42bf99180ab4344352cea2d04 (patch)
tree7deb2248fe9c0b3f7e6cb8763320d4405f1e443f /llvm
parent36c23cad151ade2ce1350c955ea7fd0ea9dcc674 (diff)
downloadbcm5719-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.h24
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;
}
OpenPOWER on IntegriCloud