aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-05-03 15:57:35 +0100
committergingerBill <bill@gingerbill.org>2021-05-03 15:57:35 +0100
commite4286d0ff9d383d03b220ac8fc52934853b35c34 (patch)
treedf49c45a57dc1b2e02a3067cc2dfb0a08e603bd2 /src
parent3a556eb3046f3f7ff1183981b261ac38e38c0c87 (diff)
Force `zero_init` in `lb_add_local` in certain cases
Diffstat (limited to 'src')
-rw-r--r--src/llvm_backend.cpp15
-rw-r--r--src/types.cpp29
2 files changed, 44 insertions, 0 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 72694e562..2c61132dd 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -3424,6 +3424,21 @@ lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, i32 p
LLVMSetAlignment(ptr, alignment);
LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
+
+
+ if (!zero_init) {
+ // If there is any padding of any kind, just zero init regardless of zero_init parameter
+ LLVMTypeKind kind = LLVMGetTypeKind(llvm_type);
+ if (kind == LLVMStructTypeKind) {
+ i64 sz = type_size_of(type);
+ if (type_size_of_struct_pretend_is_packed(type) != sz) {
+ zero_init = true;
+ }
+ } else if (kind == LLVMArrayTypeKind) {
+ zero_init = true;
+ }
+ }
+
if (zero_init) {
LLVMTypeKind kind = LLVMGetTypeKind(llvm_type);
diff --git a/src/types.cpp b/src/types.cpp
index 3fafa00d5..ffdb90c03 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -2779,7 +2779,36 @@ void type_path_pop(TypePath *tp) {
i64 type_size_of_internal (Type *t, TypePath *path);
i64 type_align_of_internal(Type *t, TypePath *path);
+i64 type_size_of(Type *t);
+i64 type_align_of(Type *t);
+i64 type_size_of_struct_pretend_is_packed(Type *ot) {
+ if (ot == nullptr) {
+ return 0;
+ }
+ Type *t = core_type(ot);
+ if (t->kind != Type_Struct) {
+ return type_size_of(ot);
+ }
+
+ if (t->Struct.is_packed) {
+ return type_size_of(ot);
+ }
+
+ i64 count = 0, size = 0, align = 1;
+
+ auto const &fields = t->Struct.fields;
+ count = fields.count;
+ if (count == 0) {
+ return 0;
+ }
+
+ for_array(i, fields) {
+ size += type_size_of(fields[i]->type);
+ }
+
+ return align_formula(size, align);
+}
i64 type_size_of(Type *t) {