mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-11 02:19:30 +00:00
Fix #6786
This commit is contained in:
@@ -911,6 +911,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty
|
||||
|
||||
bool is_local = cc.allow_local && m->curr_procedure != nullptr;
|
||||
|
||||
|
||||
if (is_type_union(type) && is_type_union_constantable(type)) {
|
||||
Type *bt = base_type(type);
|
||||
GB_ASSERT(bt->kind == Type_Union);
|
||||
@@ -1001,16 +1002,16 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty
|
||||
LLVMValueRef values[4] = {};
|
||||
unsigned value_count = 0;
|
||||
|
||||
#if LLVM_VERSION_MAJOR == 14
|
||||
#if LLVM_VERSION_MAJOR == 14
|
||||
LLVMTypeRef block_type = lb_type_internal_union_block_type(m, bt);
|
||||
values[value_count++] = llvm_const_pad_to_size(m, cv.value, block_type);
|
||||
#else
|
||||
#else
|
||||
values[value_count++] = cv.value;
|
||||
if (type_size_of(variant_type) != block_size) {
|
||||
{
|
||||
LLVMTypeRef padding_type = lb_type_padding_filler(m, block_size - type_size_of(variant_type), 1);
|
||||
values[value_count++] = LLVMConstNull(padding_type);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Type *tag_type = union_tag_type(bt);
|
||||
LLVMTypeRef llvm_tag_type = lb_type(m, tag_type);
|
||||
@@ -1026,6 +1027,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty
|
||||
}
|
||||
|
||||
res.value = LLVMConstStructInContext(m->ctx, values, value_count, true);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -2103,7 +2105,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty
|
||||
}
|
||||
}
|
||||
if (is_constant) {
|
||||
LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, tav.type, cc).value;
|
||||
LLVMValueRef elem_value = lb_const_value(m, cv_type, tav.value, tav.type, cc).value;
|
||||
if (LLVMIsConstant(elem_value) && LLVMIsConstant(values[index])) {
|
||||
values[index] = llvm_const_insert_value(m, values[index], elem_value, idx_list, idx_list_len);
|
||||
} else if (is_local) {
|
||||
|
||||
@@ -2498,7 +2498,7 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false);
|
||||
}
|
||||
|
||||
auto fields = array_make<LLVMTypeRef>(temporary_allocator(), 0, 3);
|
||||
auto fields = array_make<LLVMTypeRef>(temporary_allocator(), 0, 4);
|
||||
if (is_type_union_maybe_pointer(type)) {
|
||||
LLVMTypeRef variant = lb_type(m, type->Union.variants[0]);
|
||||
array_add(&fields, variant);
|
||||
@@ -2519,6 +2519,12 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
|
||||
LLVMTypeRef tag_type = lb_type(m, union_tag_type(type));
|
||||
array_add(&fields, block_type);
|
||||
#if LLVM_VERSION_MAJOR > 14
|
||||
{ // NOTE(bill): always add a zero-byte pad to make inline constant unions work
|
||||
LLVMTypeRef padding_type = lb_type_padding_filler(m, 0, 1);
|
||||
array_add(&fields, padding_type);
|
||||
}
|
||||
#endif
|
||||
array_add(&fields, tag_type);
|
||||
i64 used_size = lb_sizeof(block_type) + lb_sizeof(tag_type);
|
||||
i64 padding = size - used_size;
|
||||
@@ -2528,7 +2534,7 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
}
|
||||
}
|
||||
|
||||
return LLVMStructTypeInContext(ctx, fields.data, cast(unsigned)fields.count, false);
|
||||
return LLVMStructTypeInContext(ctx, fields.data, cast(unsigned)fields.count, /*packed*/true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user