wcc/ww: dotbaseaddr #128b probe gates on an untyped module-qualifier inner

The probe accepted any inner ident, hijacking same-leaf locals as a
module qualifier; gate on the untyped(module) inner only (mirror the
cstage twin). Review item #20; dual-stage rows red-proven.
This commit is contained in:
2026-06-12 09:06:51 +09:00
parent 4961a91d14
commit 94bfca761c
5 changed files with 225 additions and 24 deletions

View File

@@ -24148,14 +24148,22 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = {
if (!chained) {
lc = localfindnode(c, inner.str);
if (lc == nil) {
let gt: *node = letvartnode(c, base.str);
if (gt != nil && gt.kind == nkind.N_TARRAY) {
emitline("\tLEAQ\t");
emitsymname(c, base.str);
emitline("(SB), ");
emitline(dstreg);
emitline("\n");
return true;
// #128b is for a module-QUALIFIER inner (mod.arr): inner has no
// usable struct type. cstage gates it on inner->type==NULL||ty_err
// (cgen.c:2109). Without the gate a typed-struct global inner whose
// FIELD shares a name with an unrelated global array hijacks it
// (gs.fld -> LEAQ fld(SB)) — #20. A typed inner falls to #249 below.
let ibu: *tinfo = tichase(inner.type_: *tinfo);
if (ibu == nil || ibu.kind == tykind.TY_ERR) {
let gt: *node = letvartnode(c, base.str);
if (gt != nil && gt.kind == nkind.N_TARRAY) {
emitline("\tLEAQ\t");
emitsymname(c, base.str);
emitline("(SB), ");
emitline(dstreg);
emitline("\n");
return true;
};
};
// #249 (sibling of #135): inner is a module-GLOBAL struct value
// (let/def), not a local — lc is nil but inner.type_ is a valid

View File

@@ -1377,14 +1377,22 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = {
if (!chained) {
lc = localfindnode(c, inner.str);
if (lc == nil) {
let gt: *node = letvartnode(c, base.str);
if (gt != nil && gt.kind == nkind.N_TARRAY) {
emitline("\tLEAQ\t");
emitsymname(c, base.str);
emitline("(SB), ");
emitline(dstreg);
emitline("\n");
return true;
// #128b is for a module-QUALIFIER inner (mod.arr): inner has no
// usable struct type. cstage gates it on inner->type==NULL||ty_err
// (cgen.c:2109). Without the gate a typed-struct global inner whose
// FIELD shares a name with an unrelated global array hijacks it
// (gs.fld -> LEAQ fld(SB)) — #20. A typed inner falls to #249 below.
let ibu: *tinfo = tichase(inner.type_: *tinfo);
if (ibu == nil || ibu.kind == tykind.TY_ERR) {
let gt: *node = letvartnode(c, base.str);
if (gt != nil && gt.kind == nkind.N_TARRAY) {
emitline("\tLEAQ\t");
emitsymname(c, base.str);
emitline("(SB), ");
emitline(dstreg);
emitline("\n");
return true;
};
};
// #249 (sibling of #135): inner is a module-GLOBAL struct value
// (let/def), not a local — lc is nil but inner.type_ is a valid

View File

@@ -24148,14 +24148,22 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = {
if (!chained) {
lc = localfindnode(c, inner.str);
if (lc == nil) {
let gt: *node = letvartnode(c, base.str);
if (gt != nil && gt.kind == nkind.N_TARRAY) {
emitline("\tLEAQ\t");
emitsymname(c, base.str);
emitline("(SB), ");
emitline(dstreg);
emitline("\n");
return true;
// #128b is for a module-QUALIFIER inner (mod.arr): inner has no
// usable struct type. cstage gates it on inner->type==NULL||ty_err
// (cgen.c:2109). Without the gate a typed-struct global inner whose
// FIELD shares a name with an unrelated global array hijacks it
// (gs.fld -> LEAQ fld(SB)) — #20. A typed inner falls to #249 below.
let ibu: *tinfo = tichase(inner.type_: *tinfo);
if (ibu == nil || ibu.kind == tykind.TY_ERR) {
let gt: *node = letvartnode(c, base.str);
if (gt != nil && gt.kind == nkind.N_TARRAY) {
emitline("\tLEAQ\t");
emitsymname(c, base.str);
emitline("(SB), ");
emitline(dstreg);
emitline("\n");
return true;
};
};
// #249 (sibling of #135): inner is a module-GLOBAL struct value
// (let/def), not a local — lc is nil but inner.type_ is a valid