wcc/cgen: #124 cross-module &fn in a const — N_DOT reloc + checker accept (both-stage)
A cross-module `&module.fn` in a const emitted no static reloc (the const was never defined -> w6l undefined-reference, both stages) and wwstage's checker rejected the const fn-table. #117/#119 wired the &fn->DATAR const-data reloc for SAME-module &fn only; charclass_map (fold-6) needs cross-module (12x &ascii.isXXX). cgen: add the N_DOT arm to the &fn->symbol helper (node_fnptr_sym / nodefnptr + the two ww emit sites), emitting mafn(leaf, module-ident) -- exactly the symbol a runtime &mod.fn or a direct cross-module call already emits. The helper is the SSoT for both the scalar (#119) and tuple-row (#117) const-data paths, so one arm closes both. checker: type a cross-module `&mod.fn` as `*fn(...)` in the TK_AMP arm (the N_DOT twin of #206's N_IDENT fn-ptr synthesis, gated on a resolved SK_FN/N_FNDECL leaf), so isassignable affirmatively accepts the const table -- aligning wwstage UP to cstage's actual acceptance reason rather than by abdication. The SK_FN gate keeps a non-fn `&mod.var` from synthesizing a fn type (the one pre-existing nonfn-scalar cs!=ww slip is N_IDENT-base, untouched and reproduces same-module). One consumer-coupled commit (the checker accept gates wwstage cgen, so neither half is independently testable). Narrow: slice-row + scalar only; fixed-array (#118) and struct-field (#129) stay separate. Both stages emit the correct cross-module symbols at the right tuple-slot offsets -> byte-identical (990-997 green). Pin 949_xmod_fnptr_const_run (distinct fns so a wrong reloc is caught + the SK_FN-gate axis). This was the last fold-6 cgen blocker; charclass_map is now unblocked.
This commit is contained in:
@@ -15217,6 +15217,19 @@ node_fnptr_sym(Cg *c, Node *ev)
|
||||
{
|
||||
if (ev == NULL || ev->kind != N_UN || ev->op != TK_AMP) return NULL;
|
||||
Node *opnd = ev->lhs;
|
||||
/* #124: a cross-module `&mod.fn` — opnd is an N_DOT whose base is an
|
||||
* untyped SK_USE module ident (NULL/ty_err); the leaf chases TY_FN.
|
||||
* Mangle the leaf with the MODULE ident (not cur_mod) so the reloc
|
||||
* targets the same TEXT symbol the runtime &mod.fn / direct call emit
|
||||
* (cgen.c:4123-4144). The N_DOT arm of the #117/#119 reloc helper. */
|
||||
if (opnd && opnd->kind == N_DOT) {
|
||||
if (opnd->lhs == NULL || opnd->lhs->kind != N_IDENT
|
||||
|| (opnd->lhs->type != NULL && opnd->lhs->type != ty_err))
|
||||
return NULL;
|
||||
Type *du = type_chase_named(opnd->type);
|
||||
if (du == NULL || du->kind != TY_FN) return NULL;
|
||||
return mod_mangle_fn(c, opnd->str, opnd->lhs->str);
|
||||
}
|
||||
if (opnd == NULL || opnd->kind != N_IDENT) return NULL;
|
||||
Type *ou = type_chase_named(opnd->type);
|
||||
if (ou == NULL || ou->kind != TY_FN) return NULL;
|
||||
|
||||
Reference in New Issue
Block a user