fix: allow void (zero-sized) struct/tuple fields instead of crashing (issue 0150)
A struct/tuple/?T with a void field crashed the compiler: the field lowered to LLVM's unsized 'void' type, which traps getTypeSizeInBits. Lower a void field to a SIZED zero-byte [0 x i8] (fieldLLVMType) so the enclosing aggregate stays sized with identical element indices, and skip inserting a value for a void field in emitStructInit (the i64 placeholder would type-mismatch the [0 x i8] slot and corrupt the aggregate constant -> runtime bus error). Future(void) now works. Regression: examples/0190-types-void-struct-field-zero-sized.sx
This commit is contained in:
27
examples/0190-types-void-struct-field-zero-sized.sx
Normal file
27
examples/0190-types-void-struct-field-zero-sized.sx
Normal file
@@ -0,0 +1,27 @@
|
||||
// A `void` (zero-sized) struct/tuple field is legitimate (e.g. `Future(void)`)
|
||||
// and must NOT crash the compiler. It lowers to a zero-width `[0 x i8]` LLVM
|
||||
// slot (TypeLowering.fieldLLVMType), and aggregate init skips storing a value
|
||||
// into it (emitStructInit) — so the struct stays sized and field access past
|
||||
// the void field is correct, instead of the old unsized-type SIGTRAP / a
|
||||
// corrupt aggregate constant.
|
||||
//
|
||||
// Regression (issue 0150).
|
||||
#import "modules/std.sx";
|
||||
|
||||
Holder :: struct { v: void; ok: bool; }
|
||||
|
||||
Box :: struct($T: Type) { v: T; tag: i32; }
|
||||
|
||||
main :: () -> i32 {
|
||||
h : Holder = .{ ok = true };
|
||||
if h.ok { print("ok\n"); }
|
||||
|
||||
// Through a generic instantiated at `void`.
|
||||
b : Box(void) = .{ tag = 7 };
|
||||
print("tag={}\n", b.tag);
|
||||
|
||||
// A tuple with a void element.
|
||||
t : (void, i32) = .{ {}, 9 };
|
||||
print("t1={}\n", t.1);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
ok
|
||||
tag=7
|
||||
t1=9
|
||||
Reference in New Issue
Block a user