diff --git a/llvm/include/llvm/Support/MemAlloc.h b/llvm/include/llvm/Support/MemAlloc.h --- a/llvm/include/llvm/Support/MemAlloc.h +++ b/llvm/include/llvm/Support/MemAlloc.h @@ -24,23 +24,41 @@ 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; }