wcc/ww: size/align intercept unconditionally; unknown type is loud

The size()/align() intercept hid behind a shadow gate with no cstage
twin — a shadowed name silently folded to zero. Intercept
unconditionally and make an unresolvable type a loud error, mirroring
cstage check.c:93/1538; the dead shadow gate is dropped.
This commit is contained in:
2026-06-12 11:18:19 +09:00
parent 353b50489f
commit bd86fa5f46
3 changed files with 66 additions and 24 deletions

View File

@@ -3004,14 +3004,29 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
let isalign: bool = streq(bname, "align");
let isoffset: bool = streq(bname, "offset");
if (issize || isalign || isoffset) {
let shadowed: bool = false;
if (c.curmod.len > 0) {
if (scopelookupinmodule(c.cur, c.curmod, bname) != nil) {
shadowed = true;
// #38/F2 (review item 7): UNCONDITIONAL intercept — cstage
// gates size/align/offset on NOTHING (cmd/wcc/check.c:1538-
// 1578), unlike user-shadowable alloc/abort/assert
// (check.c:1625/1740/1755). The removed same-module shadow
// gate had no cstage twin (its "Mirrors check.c:907-960"
// cite was stale — that range is N_TFN/N_TSTRUCT layout) and
// was already dead for primary-file decls (declmod "" →
// curmod.len==0 skipped it).
if (e.list != nil) {
// size/align resolve the arg as a TYPE; an unresolvable
// name (`size(localvar)`) is LOUD here, mirroring cstage
// resolve_type "unknown type '%s'" (check.c:93) — astsize
// otherwise folded the unresolved N_TNAME to 0 silently
// (rc=0 wrong binary). offset's arg is a value N_DOT and
// keeps its own "no field" diagnostic below.
if ((issize || isalign) && e.list.kind == nkind.N_TNAME
&& tinfofornode(c, e.list) == nil) {
cerr(e.list.file);
cerr(": error: unknown type '");
cerr(e.list.str);
cerr("'\n");
c.errs += 1;
};
};
if (!shadowed) {
if (e.list != nil) {
// Post-fold the node IS an N_INTLIT-shaped
// untyped_int constant. Mirrors cstage
// cmd/wcc/check.c:926/958 which stamps
@@ -3058,7 +3073,6 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
return mktname(c, "i32");
};
};
};
};
};
};