selfhost/cmd/wcc/cgenutil: trim rhstaggedabicall N_DOT onto n.type_ (#58, A.6.3i-phase-2)

rhstaggedabicall's N_DOT arm re-derived the field type via dotfieldtnode
(a base-ident-only structlookup walk) then asked istaggedtype. The
checker now stamps the field's resolved type on the N_DOT node itself
(check.ww struct-field arm), so read src.type_ directly. typeistagged(nil)
is false, preserving the old ft==nil bail.

Polarity DOWN per rule 10: cstage's gate was already wide. cg_widen_tagged_
store reads src->type inline, NAMED-resolved, then tests TY_TAGGED
(cmd/w6c/cgen.c:1302-1305) -- no standalone helper. Pre-trim wwstage's
gate was NARROWER (dotfieldtnode required base==N_IDENT, firing only for
`ident.field`); reading src.type_ also fires for chained-dot bases
(`a.b.c`) since the checker stamps N_DOT.type_ at any depth. This aligns
wwstage UP to cstage's existing coverage. Byte-id 990-997 green confirms
the widened shape does not occur in bootstrap sources -- byte-id-neutral.

Drops one dotfieldtnode caller; the *node-returning callers
(typenodeprimresolved, indexvaluetnode, matchscrutt) stay until their
consumers migrate to *tinfo (the closing dotfield* deletion follows once
none need *node). First clean slice of that consumer migration; same
g/h-style stamp read as #55/#56.

Known pre-existing gap (filed, not introduced here): neither stage's
chained-DOT read path has a tagged-union leaf branch, so a chained-dot
tagged ABI source would store stale DX/CX/R8. Symmetric across stages
(byte-id stays green); the retained `cgdot loads AX=tag, DX=word0, ...`
comment is accurate only for ident.field bases.

make test 133/133 (quiescent tree, byte-id 990-997 green).
This commit is contained in:
2026-05-23 15:41:31 +09:00
parent 6c9a3b369e
commit 8ccda588c6
3 changed files with 18 additions and 15 deletions

View File

@@ -12952,12 +12952,13 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = {
};
// N_DOT of a tagged-typed struct field — cgdot loads
// AX=tag, DX=word0, CX=word1[, R8=word2], so downstream
// spill matches the call/index shapes.
// spill matches the call/index shapes. #58 A.6.3i-phase-2:
// read the checker-stamped n.type_ (check.ww N_DOT struct-field
// stamp) instead of re-deriving via dotfieldtnode — matches
// cstage cg_widen_tagged_store reading src->type directly
// (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false.
if (src.kind == nkind.N_DOT) {
let ft: *node = dotfieldtnode(c, src);
if (ft != nil) {
if (istaggedtype(c, ft)) { return true; };
};
if (typeistagged(src.type_: *tinfo)) { return true; };
};
return false;
};

View File

@@ -2511,12 +2511,13 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = {
};
// N_DOT of a tagged-typed struct field — cgdot loads
// AX=tag, DX=word0, CX=word1[, R8=word2], so downstream
// spill matches the call/index shapes.
// spill matches the call/index shapes. #58 A.6.3i-phase-2:
// read the checker-stamped n.type_ (check.ww N_DOT struct-field
// stamp) instead of re-deriving via dotfieldtnode — matches
// cstage cg_widen_tagged_store reading src->type directly
// (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false.
if (src.kind == nkind.N_DOT) {
let ft: *node = dotfieldtnode(c, src);
if (ft != nil) {
if (istaggedtype(c, ft)) { return true; };
};
if (typeistagged(src.type_: *tinfo)) { return true; };
};
return false;
};

View File

@@ -12952,12 +12952,13 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = {
};
// N_DOT of a tagged-typed struct field — cgdot loads
// AX=tag, DX=word0, CX=word1[, R8=word2], so downstream
// spill matches the call/index shapes.
// spill matches the call/index shapes. #58 A.6.3i-phase-2:
// read the checker-stamped n.type_ (check.ww N_DOT struct-field
// stamp) instead of re-deriving via dotfieldtnode — matches
// cstage cg_widen_tagged_store reading src->type directly
// (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false.
if (src.kind == nkind.N_DOT) {
let ft: *node = dotfieldtnode(c, src);
if (ft != nil) {
if (istaggedtype(c, ft)) { return true; };
};
if (typeistagged(src.type_: *tinfo)) { return true; };
};
return false;
};