Skip to content

Commit 32e0dfd

Browse files
committed
never call malloc with size 0
instead we return nullptr. this makes the behavior consistent across all platforms. closes #1044 closes #1045
1 parent d21a192 commit 32e0dfd

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

src/analyze.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,7 +1860,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
18601860
}
18611861

18621862
assert(!struct_type->data.structure.zero_bits_loop_flag);
1863-
assert(struct_type->data.structure.fields);
1863+
assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);
18641864
assert(decl_node->type == NodeTypeContainerDecl);
18651865

18661866
size_t field_count = struct_type->data.structure.src_field_count;
@@ -2677,8 +2677,8 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
26772677
return;
26782678
}
26792679
tag_type = enum_type;
2680+
abi_alignment_so_far = get_abi_alignment(g, enum_type); // this populates src_field_count
26802681
covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
2681-
abi_alignment_so_far = get_abi_alignment(g, enum_type);
26822682
} else {
26832683
tag_type = nullptr;
26842684
abi_alignment_so_far = 0;

src/util.hpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ static inline int clzll(unsigned long long mask) {
6565

6666
template<typename T>
6767
ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {
68+
#ifndef NDEBUG
69+
// make behavior when size == 0 portable
70+
if (count == 0)
71+
return nullptr;
72+
#endif
6873
T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
6974
if (!ptr)
7075
zig_panic("allocation failed");
@@ -73,6 +78,11 @@ ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {
7378

7479
template<typename T>
7580
ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) {
81+
#ifndef NDEBUG
82+
// make behavior when size == 0 portable
83+
if (count == 0)
84+
return nullptr;
85+
#endif
7686
T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));
7787
if (!ptr)
7888
zig_panic("allocation failed");
@@ -93,9 +103,7 @@ static inline void safe_memcpy(T *dest, const T *src, size_t count) {
93103

94104
template<typename T>
95105
static inline T *reallocate(T *old, size_t old_count, size_t new_count) {
96-
T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
97-
if (!ptr)
98-
zig_panic("allocation failed");
106+
T *ptr = reallocate_nonzero(old, old_count, new_count);
99107
if (new_count > old_count) {
100108
memset(&ptr[old_count], 0, (new_count - old_count) * sizeof(T));
101109
}
@@ -104,6 +112,11 @@ static inline T *reallocate(T *old, size_t old_count, size_t new_count) {
104112

105113
template<typename T>
106114
static inline T *reallocate_nonzero(T *old, size_t old_count, size_t new_count) {
115+
#ifndef NDEBUG
116+
// make behavior when size == 0 portable
117+
if (new_count == 0 && old == nullptr)
118+
return nullptr;
119+
#endif
107120
T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
108121
if (!ptr)
109122
zig_panic("allocation failed");

0 commit comments

Comments
 (0)