fixes
This commit is contained in:
51
examples/issue-0011.sx
Normal file
51
examples/issue-0011.sx
Normal file
@@ -0,0 +1,51 @@
|
||||
// issue-0011: Assigning to List(T).items corrupts adjacent memory when T is large
|
||||
//
|
||||
// Writing `list.items = xx 0` overwrites memory beyond the 8-byte items pointer
|
||||
// when the List's element type T is larger than 32 bytes. The corruption spills
|
||||
// into the struct field that follows the List in memory.
|
||||
//
|
||||
// Works correctly when size_of(T) <= 32.
|
||||
// Fails when size_of(T) > 32 (e.g., 40 bytes).
|
||||
//
|
||||
// Likely cause: codegen confuses size_of(T) with size_of([*]T) when generating
|
||||
// the store instruction for the items field.
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
// 40-byte struct — triggers the bug.
|
||||
// Shrink to [4]s64 (32 bytes) and the bug goes away.
|
||||
BigNode :: struct {
|
||||
data: [5]s64; // 40 bytes
|
||||
}
|
||||
|
||||
Tree :: struct {
|
||||
nodes: List(BigNode); // items(8) + len(8) + cap(8) = 24 bytes
|
||||
generation: s64; // 8 bytes — total 32 bytes
|
||||
}
|
||||
|
||||
Container :: struct {
|
||||
tree: Tree;
|
||||
sentinel: s64;
|
||||
|
||||
do_work :: (self: *Container) {
|
||||
self.tree.nodes.items = xx 0; // BUG: corrupts self.sentinel
|
||||
}
|
||||
}
|
||||
|
||||
main :: () -> void {
|
||||
obj : *Container = xx context.allocator.alloc(size_of(Container));
|
||||
memset(obj, 0, size_of(Container));
|
||||
obj.sentinel = 0xDEADBEEF;
|
||||
|
||||
print("size_of BigNode = {}\n", size_of(BigNode));
|
||||
print("before: sentinel = {}\n", obj.sentinel);
|
||||
|
||||
obj.do_work();
|
||||
|
||||
print("after: sentinel = {}\n", obj.sentinel);
|
||||
if obj.sentinel != 0xDEADBEEF {
|
||||
print("BUG: sentinel was corrupted!\n");
|
||||
} else {
|
||||
out("OK\n");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user