Commit Graph

5 Commits

Author SHA1 Message Date
f1440bf9e8 cstage+selfhost+test: mangle fn labels by module (#9)
Both stages emitted fn TEXT labels by leaf only; lib/os and lib/io
exporting the same leaves (read, write, close) collided at link.
lib/fmt + lib/log worked around with @symbol("rt_syscall") stubs.

Drop d->export from the fn skip rule in mod_collect (both stages) so
exported fns mangle as <module>.<name>. Let/def/type keep current
behavior. Skip retained for {@symbol, main, empty-module}.

Add cur_mod thread through cgfn + mod_lookup_for_fn(name, hint) at
all 4 label-emit sites (TEXT def, LEAQ N_IDENT, CALL N_IDENT, CALL
N_DOT). Wwstage mirror: emitfnname + modlookupforfn + curmod.
Invariant comment pinned in both stages.

ww2 == ww3 == ww4 byte-identical at the new label format.
706_fnlabel_mangle covers same-leaf cross-module CALL + private-leaf
cur_mod disambiguation through a fn-pointer rvalue.

Wwstage LEAQ-of-fn N_DOT (`let p = mod.fn` rvalue) is a pre-existing
gap; deferred to a follow-up. fmt/log rt_syscall stubs untouched
here; cleanup follows.
2026-05-15 23:41:01 +09:00
7f60ebbe44 cstage+test: SK_USE→SK_X promotion sets use_alias
In cmd/wcc/check.c the pass-1.5 SK_USE→SK_DEF/SK_FN/SK_VAR promotion
sites forgot to set prev->use_alias = 1 when the imported module's
top-level decl shadowed the SK_USE leaf in flat scope. Downstream
dot-prefixed lookups (resolve_typename L77, N_DOT L709) gate the
module-head walk on (SK_USE || use_alias), so `mod.flag` resolution
fell through to "unknown type". The SK_TYPE precedent at L1660 had
the line; the three sister sites at L1709/L1722/L1736 now do too,
in the same one-line shape and field-set order.

The wwstage selfhost/cmd/wcc/check.ww uses coexistence rather than
in-place promotion: SK_USE and same-leaf SK_TYPE/FN/DEF/VAR live as
separate entries differentiated by sym.mod, and scopelookupinmodule's
mod-filter already disambiguates dotted lookups — no use_alias flag
needed, so the cstage bug is structurally non-reachable there. An
architectural note at installdecl documents this divergence-by-design
and warns against porting the flag (adding a field to `sym` changes
its size and risks the wwstage cgen amalloc-undersize trap).

Audit covered every SK_USE→SK_X promotion path in check.c (4 sites:
SK_TYPE already-correct as precedent, SK_DEF/SK_FN/SK_VAR fixed). The
surfacing case was lib/fnmatch: `fn fnmatch(...)` shadows the SK_USE
leaf, so `fnmatch.flag` failed in worker-fnmatch's WIP — that test
(972_fnmatch_run) now flips PASS as live integration proof.
test/wcc/699_use_promote_alias.c pins all four rows with a single
table-driven driver (type/fn/def/var → use mod; let m: mod.flag =
mod.flag.A; return m: i32, expecting exit 42 per row). 995_self_rebuild
byte-identity holds.
2026-05-15 15:06:37 +09:00
e6045f3ada w6c+selfhost: same-module preference for bare-leaf lookup 2026-05-15 11:24:33 +09:00
66d6408cbe w6c+selfhost: cross-module same-leaf type disambiguation via Sym.mod 2026-05-15 10:26:20 +09:00
906e17b128 wcc: @test marker attributes + runner
Hare-style `@test fn check_foo() void = { ... }` now parses. The
attribute is recognised by making the args list optional in
parseattrs: `@symbol("rt_syscall")` still requires the parens;
`@test` doesn't. Same change mirrored in lib/ww/parse/decl.ww.

The runner (test/wcc/910_at_test.c) scans a fixture for
`@test fn IDENT(`, synthesises a wrapper `main()` that calls each
test fn, builds it via `ww run`, and asserts exit 0. A failing
@test would either explicitly call abort or trip a runtime trap
(div-by-zero, etc.) and the whole driver exits non-zero.

The 910_at_test target sits alongside the existing C-side test
binaries; `make test` now runs 20 tests instead of 19.

Fixture: test/wcc/data/attest_pass.ww exercises two passing tests
(simple arithmetic and a match-with-yield).
2026-05-12 03:14:20 +09:00