Browse Source

Force `zero_init` in `lb_add_local` in certain cases

gingerBill 4 years ago
parent
commit
e4286d0ff9
2 changed files with 44 additions and 0 deletions
  1. 15 0
      src/llvm_backend.cpp
  2. 29 0
      src/types.cpp

+ 15 - 0
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);
 	LLVMSetAlignment(ptr, alignment);
 
 
 	LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
 	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) {
 	if (zero_init) {
 		LLVMTypeKind kind = LLVMGetTypeKind(llvm_type);
 		LLVMTypeKind kind = LLVMGetTypeKind(llvm_type);
 
 

+ 29 - 0
src/types.cpp

@@ -2779,7 +2779,36 @@ void type_path_pop(TypePath *tp) {
 
 
 i64 type_size_of_internal (Type *t, TypePath *path);
 i64 type_size_of_internal (Type *t, TypePath *path);
 i64 type_align_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) {
 i64 type_size_of(Type *t) {