w6c,ww: mangle an imported package's fn main under separate compilation (M4 E3, #99)
The bare-`main` carve-out (which keeps the link entry's main unmangled) keyed on `leaf == "main" && imported == 0`. Under the combined path a dependency's body folds in with imported==1, so only the root's main stayed bare. Under separate compilation each package is its own unit and a dependency's body carries a path-mangling module-reset but imported==0 (#57) — so an imported `fn main` matched the carve-out, emitted a bare `TEXT main`, and collided with the root entry (`w6l: duplicate symbol main`). The combined path was unaffected, so this only surfaced under sep. Gate the carve-out with sep_isdep = (wwiout != NULL): the producer emits a .wwi output only for dependency units, never for the root/link-entry unit (root stripped, #69), symmetric on both stages. Only the root unit's main now stays bare; an imported package's main mangles on its import path (e.g. aa.bb.main). Both stages. Gate: test/wcc/989_depmain_sep.c (table-driven, dotted + single-component shapes, both stages; asserts the mangled dep main + a single bare root main + cs==ww byte-id; combined path stays neutral).
This commit is contained in:
@@ -1477,8 +1477,14 @@ mod_collect(Cg *c, Node *file)
|
||||
* primary's decls are MODULED "main", so main is NOT bare here;
|
||||
* skip it (cgfn force-emits the bare `main` label). M1 #32: only
|
||||
* the ROOT main (imported==0) stays bare; an IMPORTED `fn main`
|
||||
* mangles on its path (closes #31's dup-main by construction). */
|
||||
if (d->str && strcmp(d->str, "main") == 0 && !d->imported)
|
||||
* mangles on its path (closes #31's dup-main by construction).
|
||||
* #99: under sep a dep unit's main is imported==0 too (its body
|
||||
* is composed with a path-carrying `//ww:module-reset`, #57), so
|
||||
* imported==0 no longer means "root unit" per-unit. Gate on
|
||||
* !sep_isdep (wwiout==NULL <=> root/link-entry unit, #69) so only
|
||||
* the root's main stays bare; a dep's main mangles on its path. */
|
||||
if (d->str && strcmp(d->str, "main") == 0 && !d->imported
|
||||
&& !c->sep_isdep)
|
||||
continue;
|
||||
Mod *m = amalloc(c->a, sizeof *m);
|
||||
m->name = d->str;
|
||||
@@ -14960,8 +14966,12 @@ cgfn(Cg *c, FILE *out, Node *fn)
|
||||
* NOT a bare-module decl — removing this carve-out mangles it to
|
||||
* `main.main` (undefined `main`). #84's bare-module handling is the
|
||||
* orthogonal axis (a package-LESS `//ww:module-reset` fn, cur_mod
|
||||
* NULL), resolved in mod_lookup_for_fn, NOT here. */
|
||||
if (fn->str && strcmp(fn->str, "main") == 0 && !fn->imported)
|
||||
* NULL), resolved in mod_lookup_for_fn, NOT here. #99: gate on
|
||||
* !sep_isdep — under sep a dep unit's main is imported==0 (path-
|
||||
* carrying `//ww:module-reset`, #57); only the root/link-entry unit
|
||||
* (wwiout==NULL, #69) keeps the bare label. */
|
||||
if (fn->str && strcmp(fn->str, "main") == 0 && !fn->imported
|
||||
&& !c->sep_isdep)
|
||||
text->to = asym("main");
|
||||
else
|
||||
text->to = mafn(c, fn->str, c->cur_mod);
|
||||
|
||||
@@ -54,6 +54,14 @@ struct Cg {
|
||||
* the dep's real definition (link collision).
|
||||
* Off on the combined path (every existing
|
||||
* invocation) so M3 is a pure addition. */
|
||||
int sep_isdep; /* #99: this unit is a sep DEPENDENCY, not the
|
||||
* root/link-entry unit. Set from `wwiout != NULL`
|
||||
* in main: the producer passes -I (.wwi output)
|
||||
* to DEP units only — the root's .wwi is stripped
|
||||
* (#69), so wwiout==NULL <=> root/link-entry unit.
|
||||
* Gates the bare-`main` carve-out: a dep's `fn
|
||||
* main` must mangle on its path like any decl;
|
||||
* only the root entry stays bare. */
|
||||
};
|
||||
|
||||
/* cgen.c */
|
||||
|
||||
@@ -110,6 +110,10 @@ main(int argc, char **argv)
|
||||
|
||||
cg_init(&cg, a);
|
||||
cg.sep_mode = sepmode;
|
||||
/* #99: wwiout != NULL <=> this is a sep DEP unit (the producer passes
|
||||
* -I to deps only; the root's .wwi is stripped per #69). Gates the
|
||||
* bare-`main` carve-out so only the root/link-entry main stays bare. */
|
||||
cg.sep_isdep = (wwiout != NULL);
|
||||
cg_file(&cg, of, file);
|
||||
|
||||
if (of != stdout) fclose(of);
|
||||
|
||||
Reference in New Issue
Block a user