w6c+wwstage: aggregate let-init copy from a struct-DEF global (#268 reviewer)
The fold-1b unified arm (bb2f4e1) added an N_IDENT addressable-rhs source
setup, but the two stages gated the GLOBAL case differently: cstage used
let_islet || def_isarraydef, wwstage used isletvar || deflookup (ANY def).
On a struct-typed `def` used as an aggregate-copy rhs (`let c: T = G`)
wwstage copied the whole value (correct) while cstage truncated to the 8B
scalar tail — a cs!=ww divergence (rule-10). A struct-LET global already
copies on both, so the def gap was also an internal cstage inconsistency.
Struct defs are first-class laid-out aggregates (DATA storage + field
load, #129 A.2/A.3), so converge on the correct full copy on both: add
def_isstructdef to cstage's predicate and replace wwstage's broad
deflookup with the def_is{array,struct}def pairing already held identical
in defisaddressable. 949 +2 rows (array-def + struct-def global, full
readback, byteid=1).
This commit is contained in:
@@ -28906,8 +28906,20 @@ fn cglet(c: *cgen, n: *node) void = {
|
||||
emitline("(BP), SI\n");
|
||||
havesrc = true;
|
||||
} else {
|
||||
if (isletvar(c, rhs.str)
|
||||
|| deflookup(c, rhs.str)) {
|
||||
// rule-10: the addressable-def set must
|
||||
// equal cstage's let_islet ||
|
||||
// def_isarraydef || def_isstructdef —
|
||||
// the laid-out-aggregate globals (#129
|
||||
// A.2/A.3). Bare deflookup (any def)
|
||||
// over-copies struct-defs on wwstage
|
||||
// only; mirror the defisaddressable
|
||||
// pairing instead.
|
||||
let aggdtn: *node = defvartnode(c, rhs.str);
|
||||
let aggisdef: bool = defvarstructinfo(c, rhs.str) != nil;
|
||||
if (aggdtn != nil) {
|
||||
if (aggdtn.kind == nkind.N_TARRAY) { aggisdef = true; };
|
||||
};
|
||||
if (isletvar(c, rhs.str) || aggisdef) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymname(c, rhs.str);
|
||||
emitline("(SB), SI\n");
|
||||
|
||||
@@ -1766,8 +1766,20 @@ fn cglet(c: *cgen, n: *node) void = {
|
||||
emitline("(BP), SI\n");
|
||||
havesrc = true;
|
||||
} else {
|
||||
if (isletvar(c, rhs.str)
|
||||
|| deflookup(c, rhs.str)) {
|
||||
// rule-10: the addressable-def set must
|
||||
// equal cstage's let_islet ||
|
||||
// def_isarraydef || def_isstructdef —
|
||||
// the laid-out-aggregate globals (#129
|
||||
// A.2/A.3). Bare deflookup (any def)
|
||||
// over-copies struct-defs on wwstage
|
||||
// only; mirror the defisaddressable
|
||||
// pairing instead.
|
||||
let aggdtn: *node = defvartnode(c, rhs.str);
|
||||
let aggisdef: bool = defvarstructinfo(c, rhs.str) != nil;
|
||||
if (aggdtn != nil) {
|
||||
if (aggdtn.kind == nkind.N_TARRAY) { aggisdef = true; };
|
||||
};
|
||||
if (isletvar(c, rhs.str) || aggisdef) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymname(c, rhs.str);
|
||||
emitline("(SB), SI\n");
|
||||
|
||||
@@ -28906,8 +28906,20 @@ fn cglet(c: *cgen, n: *node) void = {
|
||||
emitline("(BP), SI\n");
|
||||
havesrc = true;
|
||||
} else {
|
||||
if (isletvar(c, rhs.str)
|
||||
|| deflookup(c, rhs.str)) {
|
||||
// rule-10: the addressable-def set must
|
||||
// equal cstage's let_islet ||
|
||||
// def_isarraydef || def_isstructdef —
|
||||
// the laid-out-aggregate globals (#129
|
||||
// A.2/A.3). Bare deflookup (any def)
|
||||
// over-copies struct-defs on wwstage
|
||||
// only; mirror the defisaddressable
|
||||
// pairing instead.
|
||||
let aggdtn: *node = defvartnode(c, rhs.str);
|
||||
let aggisdef: bool = defvarstructinfo(c, rhs.str) != nil;
|
||||
if (aggdtn != nil) {
|
||||
if (aggdtn.kind == nkind.N_TARRAY) { aggisdef = true; };
|
||||
};
|
||||
if (isletvar(c, rhs.str) || aggisdef) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymname(c, rhs.str);
|
||||
emitline("(SB), SI\n");
|
||||
|
||||
Reference in New Issue
Block a user