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) {