w6c+w6c_ww: loud-stop non-ident/non-local append spread source (#34 review)
A spread whose source was not a local ident fell PAST the spread arm: cstage continued into the single-value stores with the N_SPREAD node (garbage store), wwstage silently SKIPPED the value entirely — a silent, cs!=ww-divergent miscompile (append(ys, f()...): cs exit 0 / ww exit 144, want 3), reachable for every element kind and predating #34 for scalars. Both stages now rule-7 loud-stop the shape (deferred, task #37). Also pins the widener's already-tagged single-value source path (tagged_ident_src row, i64 + bool members) and adds the spread_call_loudstop BUILD_FAIL row — test 800 is now 15 rows / 43 fixtures.
This commit is contained in:
@@ -4149,11 +4149,23 @@ fn cgappend(c: *cgen, n: *node) void = {
|
||||
let vn: *node = sn.next;
|
||||
for (vn != nil) {
|
||||
if (vn.kind == nkind.N_SPREAD) {
|
||||
// #34 review: a non-ident/non-local spread source used
|
||||
// to be silently SKIPPED here while cstage fell past
|
||||
// its spread arm into the single-value stores with the
|
||||
// N_SPREAD node (garbage store) — divergent. Deferred
|
||||
// source shape, task #37.
|
||||
let it: *node = vn.lhs;
|
||||
if (it == nil) { vn = vn.next; continue; };
|
||||
if (it.kind != nkind.N_IDENT) { vn = vn.next; continue; };
|
||||
if (it == nil || it.kind != nkind.N_IDENT) {
|
||||
let m34p: str = "#34: append() spread source shape unsupported (rule-7)\n";
|
||||
os.write(2, m34p.ptr, m34p.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
let itlocal: *local = localfindnode(c, it.str);
|
||||
if (itlocal == nil) { vn = vn.next; continue; };
|
||||
if (itlocal == nil) {
|
||||
let m34q: str = "#34: append() spread source ident is not a local (rule-7)\n";
|
||||
os.write(2, m34q.ptr, m34q.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
let it_off: i32 = itlocal.off;
|
||||
let load_op: str = tnodeloadop(c, etnode, esz);
|
||||
emitline("\tSUBQ\t$8, SP\n");
|
||||
|
||||
Reference in New Issue
Block a user