lang: fix struct-field null/undef over-store (issue 0154)
Assigning null/--- to a struct field picked up a leaked enclosing target_type (the function's return type, set for the whole body), so constNull/constUndef built a whole-struct-typed value. The oversized store overran the field's slot and clobbered the saved frame pointer, so the function returned to 0x0. Surfaced building a by-value-returned struct whose array field precedes a pointer field (Scheduler.init()). Fix: add null_literal/undef_literal to the needs_target switch in lowerAssignment so the field's own type is used. Regression: examples/types/0193-types-sret-array-before-pointer.sx.
This commit is contained in:
28
examples/types/0193-types-sret-array-before-pointer.sx
Normal file
28
examples/types/0193-types-sret-array-before-pointer.sx
Normal file
@@ -0,0 +1,28 @@
|
||||
// Assigning `null` / `---` to a struct field must store a FIELD-typed value,
|
||||
// not pick up an enclosing `target_type` (e.g. the function's return type while
|
||||
// lowering its body) — which would build a whole-struct-typed null and emit an
|
||||
// oversized store that overruns the field's slot.
|
||||
//
|
||||
// Regression (issue 0154): `s.p = null` inside a struct-returning fn used to
|
||||
// store a 32-byte struct `zeroinitializer` through the pointer field's GEP,
|
||||
// clobbering the saved x29/x30 so the fn `ret`'d to 0x0. The array-before-
|
||||
// pointer order puts the pointer at a non-zero offset, pushing the over-store
|
||||
// off the end of the alloca. Fixed by adding null/undef literals to
|
||||
// `needs_target` in lowerAssignment.
|
||||
#import "modules/std.sx";
|
||||
S :: struct {
|
||||
arr: [2]u64; // fixed-array field FIRST
|
||||
p: *i64; // pointer field AFTER the array
|
||||
n: i64;
|
||||
}
|
||||
mk :: () -> S {
|
||||
s : S = ---;
|
||||
s.p = null; // must store a *i64 null, not a whole-struct null
|
||||
s.n = 0;
|
||||
return s;
|
||||
}
|
||||
main :: () -> i64 {
|
||||
s := mk();
|
||||
print("n {}\n", s.n); // n 0
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
n 0
|
||||
Reference in New Issue
Block a user