mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-26 15:01:31 +00:00
Merge pull request #7412 from mocompute/fix-7008
fix incorrect offset_of and size_of for unions with cyclic pointers
This commit is contained in:
@@ -2770,26 +2770,17 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
if (is_type_union_maybe_pointer(type)) {
|
||||
LLVMTypeRef variant = lb_type(m, type->Union.variants[0]);
|
||||
array_add(&fields, variant);
|
||||
} else if (type->Union.variants.count == 1) {
|
||||
LLVMTypeRef block_type = lb_type(m, type->Union.variants[0]);
|
||||
|
||||
LLVMTypeRef tag_type = lb_type(m, union_tag_type(type));
|
||||
array_add(&fields, block_type);
|
||||
array_add(&fields, tag_type);
|
||||
i64 used_size = lb_sizeof(block_type) + lb_sizeof(tag_type);
|
||||
i64 padding = size - used_size;
|
||||
if (padding > 0) {
|
||||
LLVMTypeRef padding_type = lb_type_padding_filler(m, padding, align);
|
||||
array_add(&fields, padding_type);
|
||||
}
|
||||
is_packed = true;
|
||||
} else {
|
||||
LLVMTypeRef block_type = lb_type_internal_union_block_type(m, type);
|
||||
|
||||
LLVMTypeRef tag_type = lb_type(m, union_tag_type(type));
|
||||
array_add(&fields, block_type);
|
||||
array_add(&fields, tag_type);
|
||||
i64 used_size = lb_sizeof(block_type) + lb_sizeof(tag_type);
|
||||
i64 block_size = lb_sizeof(block_type);
|
||||
if (block_size == 0) {
|
||||
block_size = type_size_of(type->Union.variants[0]);
|
||||
}
|
||||
i64 used_size = block_size + lb_sizeof(tag_type);
|
||||
i64 padding = size - used_size;
|
||||
if (padding > 0) {
|
||||
LLVMTypeRef padding_type = lb_type_padding_filler(m, padding, align);
|
||||
|
||||
@@ -40,6 +40,7 @@ set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused
|
||||
..\..\..\odin test ..\test_issue_6753.odin %COMMON% || exit /b
|
||||
..\..\..\odin check ..\test_issue_6874.odin %COMMON% 2>&1 | find /c "Error:" | findstr /x "1" || exit /b
|
||||
..\..\..\odin check ..\test_issue_6979.odin -no-entry-point %COMMON% || exit /b
|
||||
..\..\..\odin test ..\test_issue_7008.odin %COMMON% || exit /b
|
||||
..\..\..\odin check ..\test_issue_7012.odin -no-entry-point %COMMON% || exit /b
|
||||
..\..\..\odin check ..\test_issue_7260.odin -no-entry-point %COMMON% || exit /b
|
||||
..\..\..\odin check ..\test_issue_ellipsis_type_call.odin -no-entry-point %COMMON% 2>&1 | find /c "Error:" | findstr /x "10" || exit /b
|
||||
|
||||
@@ -88,6 +88,7 @@ else
|
||||
exit 1
|
||||
fi
|
||||
$ODIN check ../test_issue_6979.odin -no-entry-point $COMMON_CHECK
|
||||
$ODIN test ../test_issue_7008.odin $COMMON
|
||||
$ODIN check ../test_issue_7012.odin -no-entry-point $COMMON_CHECK
|
||||
$ODIN build ../test_issue_7037.odin $COMMON -o:none
|
||||
$ODIN test ../test_issue_7356.odin $COMMON
|
||||
|
||||
27
tests/issues/test_issue_7008.odin
Normal file
27
tests/issues/test_issue_7008.odin
Normal file
@@ -0,0 +1,27 @@
|
||||
// Tests issue #7008 https://github.com/odin-lang/Odin/issues/7008
|
||||
package test_issues
|
||||
|
||||
import "core:testing"
|
||||
import "core:slice"
|
||||
|
||||
Bar :: struct {
|
||||
p: ^Foo,
|
||||
}
|
||||
|
||||
Maybe_Bar :: union {
|
||||
Bar,
|
||||
}
|
||||
|
||||
Foo :: struct {
|
||||
bar: Maybe_Bar,
|
||||
value: byte,
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_offset_of_is_correct :: proc(t: ^testing.T) {
|
||||
foo: Foo
|
||||
foo.value = 42
|
||||
|
||||
bytes := slice.bytes_from_ptr(&foo, size_of(Foo))
|
||||
testing.expect_value(t, bytes[offset_of(foo.value)], 42)
|
||||
}
|
||||
Reference in New Issue
Block a user