w6c+wwstage: qualify N_DOT-base + addr-of value-global by dotted module (#229)

The cross-module dotted value-global read (`aa.v`) and addr-of (`&aa.v`)
still mangled their symbol via the non-preferring leaf lookup (cstage
masym / wwstage emitsymname), so they emitted `LEAQ main.v(SB)` — the
WRONG module's same-leaf global — returning 99 instead of 7. #1 fixed the
DATA def-site and the bare-ident load; these four dotted LOAD/addr sites
were the residual.

Thread the dotted module name (the `m` in `m.x`) — n->lhs->str /
opnd->lhs->str / lhs.str / basenm — into the existing value mangle
(cstage mahint, wwstage emitsymnamehint), the same polarity the TY_FN
branch beside each site already uses via mafn/emitfnname. The addr-of
spine-walk for a bare-root `&global.field` is a different shape and is
left untouched.

Byte-id-blind (the bootstrap has no colliding leaves), so a committed
runtime + cs==ww test (796) is the net.
This commit is contained in:
2026-06-01 09:57:45 +09:00
parent 07fed80fab
commit 80e7ab7cf3
6 changed files with 238 additions and 12 deletions

View File

@@ -21014,13 +21014,17 @@ fn cgdot(c: *cgen, n: *node) void = {
};
};
let mqop: str = localloadop(c, letvartnode(c, fld));
// #229: thread the dotted module (lhs.str), not c.curmod
// — the non-preferring emitsymname mis-mangled `aa.v` onto
// a same-leaf global. The TY_FN branch above already
// threads lhs.str via emitfnname.
if (streq(mqop, "MOVQ")) {
emitline("\tMOVQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, lhs.str);
emitline("(SB), AX\n");
} else {
emitline("\tLEAQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, lhs.str);
emitline("(SB), CX\n");
emitline("\t");
emitline(mqop);
@@ -21733,8 +21737,12 @@ fn cgun(c: *cgen, n: *node) void = {
emitline("(SB), AX\n");
return;
};
// #229: dotted-module value mangle
// (basenm), twin of the read — so
// &aa.v takes aa's global, not a
// same-leaf collision.
emitline("\tLEAQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, basenm);
emitline("(SB), AX\n");
return;
};

View File

@@ -2354,13 +2354,17 @@ fn cgdot(c: *cgen, n: *node) void = {
};
};
let mqop: str = localloadop(c, letvartnode(c, fld));
// #229: thread the dotted module (lhs.str), not c.curmod
// — the non-preferring emitsymname mis-mangled `aa.v` onto
// a same-leaf global. The TY_FN branch above already
// threads lhs.str via emitfnname.
if (streq(mqop, "MOVQ")) {
emitline("\tMOVQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, lhs.str);
emitline("(SB), AX\n");
} else {
emitline("\tLEAQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, lhs.str);
emitline("(SB), CX\n");
emitline("\t");
emitline(mqop);
@@ -3073,8 +3077,12 @@ fn cgun(c: *cgen, n: *node) void = {
emitline("(SB), AX\n");
return;
};
// #229: dotted-module value mangle
// (basenm), twin of the read — so
// &aa.v takes aa's global, not a
// same-leaf collision.
emitline("\tLEAQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, basenm);
emitline("(SB), AX\n");
return;
};

View File

@@ -21014,13 +21014,17 @@ fn cgdot(c: *cgen, n: *node) void = {
};
};
let mqop: str = localloadop(c, letvartnode(c, fld));
// #229: thread the dotted module (lhs.str), not c.curmod
// — the non-preferring emitsymname mis-mangled `aa.v` onto
// a same-leaf global. The TY_FN branch above already
// threads lhs.str via emitfnname.
if (streq(mqop, "MOVQ")) {
emitline("\tMOVQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, lhs.str);
emitline("(SB), AX\n");
} else {
emitline("\tLEAQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, lhs.str);
emitline("(SB), CX\n");
emitline("\t");
emitline(mqop);
@@ -21733,8 +21737,12 @@ fn cgun(c: *cgen, n: *node) void = {
emitline("(SB), AX\n");
return;
};
// #229: dotted-module value mangle
// (basenm), twin of the read — so
// &aa.v takes aa's global, not a
// same-leaf collision.
emitline("\tLEAQ\t");
emitsymname(c, fld);
emitsymnamehint(c, fld, basenm);
emitline("(SB), AX\n");
return;
};