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

@@ -2713,8 +2713,13 @@ cgexpr(Cg *c, Node *n, Local *locals)
opnd->lhs->str),
areg(D_AX));
else
/* #229: dotted-module value
* mangle (twin of the read), so
* &aa.v takes aa's global, not a
* same-leaf collision. */
ins2(c, A_LEAQ,
masym(c, opnd->str),
mahint(c, opnd->str,
opnd->lhs->str),
areg(D_AX));
break;
}
@@ -6774,10 +6779,17 @@ cgexpr(Cg *c, Node *n, Local *locals)
* registry-without-tnode shape agrees byte-for-byte. */
int mqop = let_islet(n->str)
? localloadop(n->type) : A_MOVQ;
/* #229: thread the DOTTED module (the `m` in `m.x`) into
* the value mangle, not cur_mod — masym's non-preferring
* leaf lookup mis-mangled `aa.v` onto another module's
* same-leaf global (read the WRONG global). The TY_FN
* branch above already uses n->lhs->str via mafn. */
if (mqop == A_MOVQ) {
ins2(c, A_MOVQ, masym(c, n->str), areg(D_AX));
ins2(c, A_MOVQ,
mahint(c, n->str, n->lhs->str), areg(D_AX));
} else {
ins2(c, A_LEAQ, masym(c, n->str), areg(D_CX));
ins2(c, A_LEAQ,
mahint(c, n->str, n->lhs->str), areg(D_CX));
ins2(c, mqop, amem(D_CX, 0), areg(D_AX));
}
goto dot_done;