selfhost+cstage+test: module-scope mklabel labels (#13)
Latent silent miscompile: cstage + wwstage mklabel emitted <fn>_<prefix>_<seq> with no module qualification, so two top-level fns sharing a leaf across modules (e.g. bytes.index + strings.index) emitted colliding labels into the same combined .s. Last assembler symbol-definition won; JNE/JMP rel32 resolved to the wrong fn's body. Repro (HEAD pre-fix): two_modules_same_leaf row in 750 — mod1.locate + mod2.locate sharing match-over-(u8|[]u8)+for shape. mod1.locate's JMP misresolved into mod2's body, exit 10. Post-fix: exit 0. Latent already at HEAD: bytes.contains_match_next_1 + strings.contains_match_next_1 collide today but the corpus had no forwarding path that surfaced it. cmd/w6c/cgen.c + selfhost/cmd/wcc/cgen.ww mklabel: prepend <module>. when c->cur_mod / c.curmod non-NULL/non-empty. Plan-9 convention extension: TEXT directive already uses <module>.<fnname> (lex.c:18 a_isidcont accepts '.'); mklabel now mirrors that for local labels. Both stages symmetric per rule 10. Fragment input (no `package`) collapses to pre-fix shape — no cross-unit risk. 750_mklabel_modscoped: table-driven 3 rows x 2 stages = 6 sub-cases (two_modules_same_leaf, bytes_strings_contains, same_module_same_leaf non-regression). All required substrings asserted via grep + runtime rc check. make test 124/124; ww2==ww3==ww4 byte-id holds via 995_self_rebuild. @-prefix slot keys (cg_tagbase, cg_tagscr, @retscr) are orthogonal (local_alloc keys, not mklabel emissions).
This commit is contained in:
@@ -768,13 +768,23 @@ fn emitoff(v: i64) void = {
|
||||
if (v != 0i64) { emitint(v); };
|
||||
};
|
||||
|
||||
// mklabel — fresh label "<fnname>_<prefix>_<seq>". Returns an
|
||||
// arena-owned str. Mirrors C cgen's mklabel so diffs match.
|
||||
// mklabel — fresh label "<module>.<fnname>_<prefix>_<seq>" (bare
|
||||
// "<fnname>_..." when curmod is empty). Returns an arena-owned str.
|
||||
// Mirrors C cgen's mklabel so diffs match. Module-qualified to
|
||||
// avoid cross-module same-leaf collisions (task #13); w6a accepts
|
||||
// '.' in label-cont (lex.c:18).
|
||||
fn mklabel(c: *cgen, prefix: str) str = {
|
||||
let buf: [128]u8;
|
||||
let i: i32 = 0;
|
||||
let fname: str = c.fnname;
|
||||
let mname: str = c.curmod;
|
||||
let j: i32 = 0;
|
||||
for (j < mname.len) {
|
||||
buf[i] = mname[j];
|
||||
i += 1; j += 1;
|
||||
};
|
||||
if (mname.len > 0) { buf[i] = 46u8; i += 1; }; // '.'
|
||||
let fname: str = c.fnname;
|
||||
j = 0;
|
||||
for (j < fname.len) {
|
||||
buf[i] = fname[j];
|
||||
i += 1; j += 1;
|
||||
|
||||
Reference in New Issue
Block a user