8481a05c3ab4f077b4130fe0299f2bd66b6b9e71
A bare cross-module value-global load mis-qualified its symbol: cgen mangled it with curmod via a non-preferring leaf lookup, so an exported `let v` in module aa emitted both its DATA storage AND its bare-load as main.v, colliding with main's private v. aa.getv() returned 99, not 7. Functions were already correct (they thread a cur_mod hint via mafn / emitfnname); value-globals did not. Both stages emitted IDENTICAL wrong asm, so the byte-id gate was blind to it; combined.ww (frontend) is clean -- the bug is purely in cgen. This is the cgen residual of #55 (#1 cgen value-global module-qualifier). Fix, symmetric in cmd/w6c/cgen.c + selfhost/cmd/wcc/{cgen,cgenexpr}.ww: reference-site mangle uses the resolved module (curmod-prefer for bare idents); definition/DATA-site mangle uses the decl's own module (d->module / d.nmod) -- threaded per-site the way fns already do, via mahint / emitsymnamehint. The fn-mangle path is left byte-for-byte untouched. Deviation from the signed-off spec (ratified by rob-pike after this finding): the spec prescribed reusing the fn lookup (mod_mangle_fn / modlookupforfn), but its first-match fallback mis-fires for value- globals -- mod_collect export-skips exported non-fn decls (cgen.c:1059) to keep their bare-name data ABI, so an exported leaf is absent from the module map and the fallback grabs another module's same-leaf private global. The value path therefore uses a distinct exact-(name,module)-or- bare lookup (mod_lookup_value / modlookupvalue): mangle only on an exact match, else stay bare. Byte-id-neutral on all existing single-owner code; exported globals stay bare (ABI preserved), private stay module-qualified. Honest boundary (rule 7): if two modules BOTH export the same value leaf, both stay bare and the linker sees a duplicate symbol -- a correct, loud, link-time ABI clash (like C), NOT a silent miscompile; left to the linker, not papered over with a cgen heuristic. Test: test/wcc/795_xmod_valglobal_run.c -- runtime (the exported global read returns its own value, not the colliding private one) + cs==ww byte-id, across i32-let / def-const / f64-let. Sibling to the checker test 794_xmod_ident_prefer, which deliberately omitted byte-id because this cgen bug diverged the asm independently.
Description
No description provided
Languages
C
89.4%
Python
7.2%
Makefile
2.3%
Shell
0.8%
Assembly
0.3%