authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-04 14:09:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-04 14:09:31-04:00
log32e0dfd4f0dab351a024e7680280343db5d7c43e
tree7e2adc8de09eeb4f8d8319979d2c343fbfe919ca
parentd21a1922eb5d76b9b0d0611eaeb42c91f83234ab

never call malloc with size 0

instead we return nullptr. this makes the behavior consistent across all platforms. closes #1044 closes #1045

2 files changed, 18 insertions(+), 5 deletions(-)

src/analyze.cpp+2-2
...@@ -1860,7 +1860,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {...@@ -1860,7 +1860,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
1860 }1860 }
18611861
1862 assert(!struct_type->data.structure.zero_bits_loop_flag);1862 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);
1864 assert(decl_node->type == NodeTypeContainerDecl);1864 assert(decl_node->type == NodeTypeContainerDecl);
18651865
1866 size_t field_count = struct_type->data.structure.src_field_count;1866 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) {...@@ -2677,8 +2677,8 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2677 return;2677 return;
2678 }2678 }
2679 tag_type = enum_type;2679 tag_type = enum_type;
2680 abi_alignment_so_far = get_abi_alignment(g, enum_type); // this populates src_field_count
2680 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);2681 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
2681 abi_alignment_so_far = get_abi_alignment(g, enum_type);
2682 } else {2682 } else {
2683 tag_type = nullptr;2683 tag_type = nullptr;
2684 abi_alignment_so_far = 0;2684 abi_alignment_so_far = 0;
src/util.hpp+16-3
...@@ -65,6 +65,11 @@ static inline int clzll(unsigned long long mask) {...@@ -65,6 +65,11 @@ static inline int clzll(unsigned long long mask) {
6565
66template<typename T>66template<typename T>
67ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {67ATTRIBUTE_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
68 T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));73 T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
69 if (!ptr)74 if (!ptr)
70 zig_panic("allocation failed");75 zig_panic("allocation failed");
...@@ -73,6 +78,11 @@ ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {...@@ -73,6 +78,11 @@ ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {
7378
74template<typename T>79template<typename T>
75ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) {80ATTRIBUTE_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
76 T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));86 T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));
77 if (!ptr)87 if (!ptr)
78 zig_panic("allocation failed");88 zig_panic("allocation failed");
...@@ -93,9 +103,7 @@ static inline void safe_memcpy(T *dest, const T *src, size_t count) {...@@ -93,9 +103,7 @@ static inline void safe_memcpy(T *dest, const T *src, size_t count) {
93103
94template<typename T>104template<typename T>
95static inline T *reallocate(T *old, size_t old_count, size_t new_count) {105static 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)));106 T *ptr = reallocate_nonzero(old, old_count, new_count);
97 if (!ptr)
98 zig_panic("allocation failed");
99 if (new_count > old_count) {107 if (new_count > old_count) {
100 memset(&ptr[old_count], 0, (new_count - old_count) * sizeof(T));108 memset(&ptr[old_count], 0, (new_count - old_count) * sizeof(T));
101 }109 }
...@@ -104,6 +112,11 @@ static inline T *reallocate(T *old, size_t old_count, size_t new_count) {...@@ -104,6 +112,11 @@ static inline T *reallocate(T *old, size_t old_count, size_t new_count) {
104112
105template<typename T>113template<typename T>
106static inline T *reallocate_nonzero(T *old, size_t old_count, size_t new_count) {114static 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
107 T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));120 T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
108 if (!ptr)121 if (!ptr)
109 zig_panic("allocation failed");122 zig_panic("allocation failed");