w6c: variant-tag miss is loud, never tag 0 (rule 7)
Every variant-index lookup miss (-1) was silently clamped to tag 0 across both stages: tagged return (value + bare-void), widen store (struct/slice/str/float/scalar arms + push fast path + field store), widen tag-remap (identity scan + emit loop), match case compare, is/as typetest, tryprop error remap, and the alloc-nomem propagation (clamped to 1). All misses are checker-rejected upstream today, so the clamps were dead -- but any future checker/cgen seam gap would mis-tag silently (wrong arm, wrong error, false success). Rule 7: each site now hard-stops with a per-construct diagnostic; nullable arms keep their raw -1 by design (a miss encodes the void polarity for `case null`). Corpus asm byte-unchanged; bootstrap fixed point holds.
This commit is contained in:
@@ -2671,7 +2671,9 @@ cg_widen_tag_remap(Cg *c, Type *du, Type *su, int slot_off)
|
|||||||
int identity = 1, idx = 0;
|
int identity = 1, idx = 0;
|
||||||
for (Tparam *p = su->params; p; p = p->next, idx++) {
|
for (Tparam *p = su->params; p; p = p->next, idx++) {
|
||||||
int di = cg_tag_for_variant(du, p->type);
|
int di = cg_tag_for_variant(du, p->type);
|
||||||
if (di < 0) di = 0;
|
if (di < 0)
|
||||||
|
fatal("tagged widen: source variant missing "
|
||||||
|
"from dst union (rule 7)");
|
||||||
if (di != idx) { identity = 0; break; }
|
if (di != idx) { identity = 0; break; }
|
||||||
}
|
}
|
||||||
if (identity) return;
|
if (identity) return;
|
||||||
@@ -2681,7 +2683,9 @@ cg_widen_tag_remap(Cg *c, Type *du, Type *su, int slot_off)
|
|||||||
for (Tparam *p = su->params; p; p = p->next, idx++) {
|
for (Tparam *p = su->params; p; p = p->next, idx++) {
|
||||||
const char *next = mklabel(c, "remap_next");
|
const char *next = mklabel(c, "remap_next");
|
||||||
int di = cg_tag_for_variant(du, p->type);
|
int di = cg_tag_for_variant(du, p->type);
|
||||||
if (di < 0) di = 0;
|
if (di < 0)
|
||||||
|
fatal("tagged widen: source variant missing "
|
||||||
|
"from dst union (rule 7)");
|
||||||
ins2(c, A_CMPQ, aimm(idx), areg(D_AX));
|
ins2(c, A_CMPQ, aimm(idx), areg(D_AX));
|
||||||
ins1(c, A_JNE, abranch(next));
|
ins1(c, A_JNE, abranch(next));
|
||||||
ins2(c, A_MOVQ, aimm(di), areg(D_AX));
|
ins2(c, A_MOVQ, aimm(di), areg(D_AX));
|
||||||
@@ -3079,7 +3083,7 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
}
|
}
|
||||||
foff += wide ? 24 : 8;
|
foff += wide ? 24 : 8;
|
||||||
}
|
}
|
||||||
ins2(c, A_MOVQ, aimm(tag < 0 ? 0 : tag),
|
ins2(c, A_MOVQ, aimm(tag),
|
||||||
amem(D_BP, write_off + 0));
|
amem(D_BP, write_off + 0));
|
||||||
if (via_outer) goto copy_out;
|
if (via_outer) goto copy_out;
|
||||||
return;
|
return;
|
||||||
@@ -3149,6 +3153,9 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
ins2(c, A_MOVQ, areg(D_AX),
|
ins2(c, A_MOVQ, areg(D_AX),
|
||||||
amem(D_BP, write_off + k));
|
amem(D_BP, write_off + k));
|
||||||
int tag = cg_tag_for_variant(du, st);
|
int tag = cg_tag_for_variant(du, st);
|
||||||
|
if (tag < 0)
|
||||||
|
fatal("tagged widen: no variant tag for source "
|
||||||
|
"(rule 7)");
|
||||||
if (src->kind == N_IDENT) {
|
if (src->kind == N_IDENT) {
|
||||||
int soff = localfind(*locals_p, src->str);
|
int soff = localfind(*locals_p, src->str);
|
||||||
int ssz = (int)su->size;
|
int ssz = (int)su->size;
|
||||||
@@ -3198,7 +3205,7 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
cg_structlit_fill(c, locals_p, su, src,
|
cg_structlit_fill(c, locals_p, su, src,
|
||||||
DST_BP, 0, NULL, write_off + 8);
|
DST_BP, 0, NULL, write_off + 8);
|
||||||
}
|
}
|
||||||
ins2(c, A_MOVQ, aimm(tag < 0 ? 0 : tag),
|
ins2(c, A_MOVQ, aimm(tag),
|
||||||
amem(D_BP, write_off + 0));
|
amem(D_BP, write_off + 0));
|
||||||
if (via_outer) goto copy_out;
|
if (via_outer) goto copy_out;
|
||||||
return;
|
return;
|
||||||
@@ -3214,7 +3221,10 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
ins2(c, A_MOVQ, areg(D_BX), amem(D_BP, write_off + 16));
|
ins2(c, A_MOVQ, areg(D_BX), amem(D_BP, write_off + 16));
|
||||||
ins2(c, A_MOVQ, areg(D_CX), amem(D_BP, write_off + 24));
|
ins2(c, A_MOVQ, areg(D_CX), amem(D_BP, write_off + 24));
|
||||||
int tag = cg_tag_for_variant(du, st);
|
int tag = cg_tag_for_variant(du, st);
|
||||||
ins2(c, A_MOVQ, aimm(tag < 0 ? 0 : tag),
|
if (tag < 0)
|
||||||
|
fatal("tagged widen: no variant tag for source "
|
||||||
|
"(rule 7)");
|
||||||
|
ins2(c, A_MOVQ, aimm(tag),
|
||||||
amem(D_BP, write_off + 0));
|
amem(D_BP, write_off + 0));
|
||||||
if (via_outer) goto copy_out;
|
if (via_outer) goto copy_out;
|
||||||
return;
|
return;
|
||||||
@@ -3246,7 +3256,10 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
amem(D_BP, write_off + k));
|
amem(D_BP, write_off + k));
|
||||||
}
|
}
|
||||||
int tag = cg_tag_for_variant(du, st);
|
int tag = cg_tag_for_variant(du, st);
|
||||||
ins2(c, A_MOVQ, aimm(tag < 0 ? 0 : tag),
|
if (tag < 0)
|
||||||
|
fatal("tagged widen: no variant tag for source "
|
||||||
|
"(rule 7)");
|
||||||
|
ins2(c, A_MOVQ, aimm(tag),
|
||||||
amem(D_BP, write_off + 0));
|
amem(D_BP, write_off + 0));
|
||||||
if (via_outer) goto copy_out;
|
if (via_outer) goto copy_out;
|
||||||
return;
|
return;
|
||||||
@@ -3266,7 +3279,10 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
amem(D_BP, write_off + k));
|
amem(D_BP, write_off + k));
|
||||||
}
|
}
|
||||||
int tag = cg_tag_for_variant(du, st);
|
int tag = cg_tag_for_variant(du, st);
|
||||||
ins2(c, A_MOVQ, aimm(tag < 0 ? 0 : tag), amem(D_BP, write_off + 0));
|
if (tag < 0)
|
||||||
|
fatal("tagged widen: no variant tag for source "
|
||||||
|
"(rule 7)");
|
||||||
|
ins2(c, A_MOVQ, aimm(tag), amem(D_BP, write_off + 0));
|
||||||
copy_out:
|
copy_out:
|
||||||
if (via_outer) {
|
if (via_outer) {
|
||||||
/* cgexpr above clobbered base_reg — reload from spill, then
|
/* cgexpr above clobbered base_reg — reload from spill, then
|
||||||
@@ -3318,7 +3334,9 @@ cg_widen_tagged_push(Cg *c, Local **locals_p, Type *dst, Node *src, int sz)
|
|||||||
/* Direct-push fast path: str / slice / scalar / pointer. */
|
/* Direct-push fast path: str / slice / scalar / pointer. */
|
||||||
cgexpr(c, src, *locals_p);
|
cgexpr(c, src, *locals_p);
|
||||||
int tag = cg_tag_for_variant(du, st);
|
int tag = cg_tag_for_variant(du, st);
|
||||||
if (tag < 0) tag = 0;
|
if (tag < 0)
|
||||||
|
fatal("tagged widen: no variant tag for source "
|
||||||
|
"(rule 7)");
|
||||||
if (type_isstr(st) || (su && su->kind == TY_STR)) {
|
if (type_isstr(st) || (su && su->kind == TY_STR)) {
|
||||||
/* str IS []u8: slot 32 [+0]=tag, [+8]=ptr, [+16]=len,
|
/* str IS []u8: slot 32 [+0]=tag, [+8]=ptr, [+16]=len,
|
||||||
* [+24]=cap — same shape as the slice arm below. Push
|
* [+24]=cap — same shape as the slice arm below. Push
|
||||||
@@ -5983,9 +6001,13 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
|||||||
areg(D_AX));
|
areg(D_AX));
|
||||||
int v58tag =
|
int v58tag =
|
||||||
cg_tag_for_variant(fu, st);
|
cg_tag_for_variant(fu, st);
|
||||||
|
if (v58tag < 0)
|
||||||
|
fatal("tagged widen: "
|
||||||
|
"no variant tag "
|
||||||
|
"for source "
|
||||||
|
"(rule 7)");
|
||||||
ins2(c, A_MOVQ,
|
ins2(c, A_MOVQ,
|
||||||
aimm(v58tag < 0
|
aimm(v58tag),
|
||||||
? 0 : v58tag),
|
|
||||||
amem(D_BX, foff + 0));
|
amem(D_BX, foff + 0));
|
||||||
ins2(c, A_MOVQ,
|
ins2(c, A_MOVQ,
|
||||||
areg(D_AX),
|
areg(D_AX),
|
||||||
@@ -11165,23 +11187,32 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
|||||||
* if the tag matches any of the alts,
|
* if the tag matches any of the alts,
|
||||||
* jump to body; otherwise to the next
|
* jump to body; otherwise to the next
|
||||||
* case. */
|
* case. */
|
||||||
|
if (tag < 0)
|
||||||
|
fatal("tagged match: case type "
|
||||||
|
"not in union (rule 7)");
|
||||||
char *body = mklabel(c, "match_body");
|
char *body = mklabel(c, "match_body");
|
||||||
ins2(c, A_CMPQ, aimm(tag < 0 ? 0 : tag),
|
ins2(c, A_CMPQ, aimm(tag),
|
||||||
areg(D_AX));
|
areg(D_AX));
|
||||||
ins1(c, A_JE, abranch(body));
|
ins1(c, A_JE, abranch(body));
|
||||||
for (Node *alt = cs->list; alt;
|
for (Node *alt = cs->list; alt;
|
||||||
alt = alt->next) {
|
alt = alt->next) {
|
||||||
int atag = cg_tag_for_variant(
|
int atag = cg_tag_for_variant(
|
||||||
su, alt->type);
|
su, alt->type);
|
||||||
|
if (atag < 0)
|
||||||
|
fatal("tagged match: case type "
|
||||||
|
"not in union (rule 7)");
|
||||||
ins2(c, A_CMPQ,
|
ins2(c, A_CMPQ,
|
||||||
aimm(atag < 0 ? 0 : atag),
|
aimm(atag),
|
||||||
areg(D_AX));
|
areg(D_AX));
|
||||||
ins1(c, A_JE, abranch(body));
|
ins1(c, A_JE, abranch(body));
|
||||||
}
|
}
|
||||||
ins1(c, A_JMP, abranch(next));
|
ins1(c, A_JMP, abranch(next));
|
||||||
label(c, body);
|
label(c, body);
|
||||||
} else {
|
} else {
|
||||||
ins2(c, A_CMPQ, aimm(tag < 0 ? 0 : tag),
|
if (tag < 0)
|
||||||
|
fatal("tagged match: case type "
|
||||||
|
"not in union (rule 7)");
|
||||||
|
ins2(c, A_CMPQ, aimm(tag),
|
||||||
areg(D_AX));
|
areg(D_AX));
|
||||||
ins1(c, A_JNE, abranch(next));
|
ins1(c, A_JNE, abranch(next));
|
||||||
}
|
}
|
||||||
@@ -11348,7 +11379,9 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
|||||||
for (Tparam *p = u->params; p; p = p->next, i++) {
|
for (Tparam *p = u->params; p; p = p->next, i++) {
|
||||||
if (!cg_variant_is_error(u, i)) continue;
|
if (!cg_variant_is_error(u, i)) continue;
|
||||||
int j = cg_tag_for_variant(r, p->type);
|
int j = cg_tag_for_variant(r, p->type);
|
||||||
if (j < 0) j = 0;
|
if (j < 0)
|
||||||
|
fatal("tryprop: error variant missing "
|
||||||
|
"from fn return union (rule 7)");
|
||||||
if (j == i) continue;
|
if (j == i) continue;
|
||||||
char *skip = mklabel(c, "tryprop_skip");
|
char *skip = mklabel(c, "tryprop_skip");
|
||||||
ins2(c, A_CMPQ, aimm(i), areg(D_AX));
|
ins2(c, A_CMPQ, aimm(i), areg(D_AX));
|
||||||
@@ -11586,7 +11619,10 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
|||||||
ins1(c, A_JNE, abranch(ne));
|
ins1(c, A_JNE, abranch(ne));
|
||||||
} else {
|
} else {
|
||||||
int tag = cg_tag_for_variant(u, vt);
|
int tag = cg_tag_for_variant(u, vt);
|
||||||
ins2(c, A_CMPQ, aimm(tag < 0 ? 0 : tag), areg(D_AX));
|
if (tag < 0)
|
||||||
|
fatal("tagged typetest: type not in union "
|
||||||
|
"(rule 7)");
|
||||||
|
ins2(c, A_CMPQ, aimm(tag), areg(D_AX));
|
||||||
ins1(c, A_JNE, abranch(ne));
|
ins1(c, A_JNE, abranch(ne));
|
||||||
}
|
}
|
||||||
ins2(c, A_MOVQ, aimm(1), areg(D_AX));
|
ins2(c, A_MOVQ, aimm(1), areg(D_AX));
|
||||||
@@ -11709,8 +11745,11 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int tag = cg_tag_for_variant(u, vt);
|
int tag = cg_tag_for_variant(u, vt);
|
||||||
|
if (tag < 0)
|
||||||
|
fatal("tagged typetest: type not in union "
|
||||||
|
"(rule 7)");
|
||||||
ins2(c, A_MOVQ, amem(D_BP, sl_off + 0), areg(D_AX));
|
ins2(c, A_MOVQ, amem(D_BP, sl_off + 0), areg(D_AX));
|
||||||
ins2(c, A_CMPQ, aimm(tag < 0 ? 0 : tag), areg(D_AX));
|
ins2(c, A_CMPQ, aimm(tag), areg(D_AX));
|
||||||
ins1(c, A_JE, abranch(ok));
|
ins1(c, A_JE, abranch(ok));
|
||||||
ins2(c, A_MOVQ, aimm(1), areg(D_DI));
|
ins2(c, A_MOVQ, aimm(1), areg(D_DI));
|
||||||
ins2(c, A_MOVQ, aimm(60), areg(D_AX));
|
ins2(c, A_MOVQ, aimm(60), areg(D_AX));
|
||||||
@@ -13531,7 +13570,9 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
|||||||
Type *r = cg_ret_type;
|
Type *r = cg_ret_type;
|
||||||
r = type_chase_named(r);
|
r = type_chase_named(r);
|
||||||
int nidx = cg_tag_for_variant(r, ty_nomem);
|
int nidx = cg_tag_for_variant(r, ty_nomem);
|
||||||
if (nidx < 0) nidx = 1;
|
if (nidx < 0)
|
||||||
|
fatal("tryprop: no nomem variant "
|
||||||
|
"in fn return union (rule 7)");
|
||||||
ins2(c, A_MOVQ, aimm(nidx), areg(D_AX));
|
ins2(c, A_MOVQ, aimm(nidx), areg(D_AX));
|
||||||
ins2(c, A_MOVQ, areg(D_BP), areg(D_SP));
|
ins2(c, A_MOVQ, areg(D_BP), areg(D_SP));
|
||||||
ins1(c, A_POPQ, areg(D_BP));
|
ins1(c, A_POPQ, areg(D_BP));
|
||||||
@@ -14130,7 +14171,9 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
|||||||
* slot and the caller reads memory. */
|
* slot and the caller reads memory. */
|
||||||
if (cg_sret_retsize(rt) > 0) {
|
if (cg_sret_retsize(rt) > 0) {
|
||||||
int tag = cg_tag_for_variant(rt, ty_void);
|
int tag = cg_tag_for_variant(rt, ty_void);
|
||||||
if (tag < 0) tag = 0;
|
if (tag < 0)
|
||||||
|
fatal("tagged return: no void "
|
||||||
|
"variant (rule 7)");
|
||||||
ins2(c, A_MOVQ,
|
ins2(c, A_MOVQ,
|
||||||
amem(D_BP, cg_sret_arg_off),
|
amem(D_BP, cg_sret_arg_off),
|
||||||
areg(D_BX));
|
areg(D_BX));
|
||||||
@@ -14150,7 +14193,9 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
|||||||
ins2(c, A_MOVQ, aimm(0), areg(D_AX));
|
ins2(c, A_MOVQ, aimm(0), areg(D_AX));
|
||||||
} else {
|
} else {
|
||||||
int tag = cg_tag_for_variant(rt, ty_void);
|
int tag = cg_tag_for_variant(rt, ty_void);
|
||||||
if (tag < 0) tag = 0;
|
if (tag < 0)
|
||||||
|
fatal("tagged return: no void "
|
||||||
|
"variant (rule 7)");
|
||||||
ins2(c, A_MOVQ, aimm(tag), areg(D_AX));
|
ins2(c, A_MOVQ, aimm(tag), areg(D_AX));
|
||||||
}
|
}
|
||||||
ins2(c, A_MOVQ, areg(D_BP), areg(D_SP));
|
ins2(c, A_MOVQ, areg(D_BP), areg(D_SP));
|
||||||
@@ -14266,6 +14311,10 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
|||||||
* caller (e.g. a slice-stride IMULQ) would
|
* caller (e.g. a slice-stride IMULQ) would
|
||||||
* land in slot+16 / slot+24. (Task #18.) */
|
* land in slot+16 / slot+24. (Task #18.) */
|
||||||
int tag = cg_tag_for_variant(rt, vt);
|
int tag = cg_tag_for_variant(rt, vt);
|
||||||
|
if (tag < 0)
|
||||||
|
fatal("tagged return: no variant "
|
||||||
|
"tag for return value "
|
||||||
|
"(rule 7)");
|
||||||
int rsz = (int)rt->size;
|
int rsz = (int)rt->size;
|
||||||
cgexpr(c, n->lhs, *locals);
|
cgexpr(c, n->lhs, *locals);
|
||||||
if (type_isslice(vt)) {
|
if (type_isslice(vt)) {
|
||||||
@@ -14332,7 +14381,7 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
|||||||
ins2(c, A_MOVQ, aimm(0),
|
ins2(c, A_MOVQ, aimm(0),
|
||||||
areg(D_R8));
|
areg(D_R8));
|
||||||
}
|
}
|
||||||
ins2(c, A_MOVQ, aimm(tag < 0 ? 0 : tag),
|
ins2(c, A_MOVQ, aimm(tag),
|
||||||
areg(D_AX));
|
areg(D_AX));
|
||||||
} else {
|
} else {
|
||||||
/* Struct variant or tagged-subset:
|
/* Struct variant or tagged-subset:
|
||||||
|
|||||||
@@ -544,7 +544,11 @@ fn cgtryprop(c: *cgen, n: *syntax.node) void = {
|
|||||||
for (p != nil) {
|
for (p != nil) {
|
||||||
if (variantiserror(u, i)) {
|
if (variantiserror(u, i)) {
|
||||||
let j: i32 = flatvariantidxt(r, p.type_, false);
|
let j: i32 = flatvariantidxt(r, p.type_, false);
|
||||||
if (j < 0) { j = 0; };
|
if (j < 0) {
|
||||||
|
let mtp: str = "tryprop: error variant missing from fn return union (rule 7)\n";
|
||||||
|
os.write(2, mtp.ptr, mtp.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
if (j != i) {
|
if (j != i) {
|
||||||
let skip: str = mklabel(c, "tryprop_skip");
|
let skip: str = mklabel(c, "tryprop_skip");
|
||||||
emitline("\tCMPQ\t$");
|
emitline("\tCMPQ\t$");
|
||||||
@@ -796,7 +800,11 @@ fn cgtypetest(c: *cgen, n: *syntax.node) void = {
|
|||||||
emitline("\tJNE\t");
|
emitline("\tJNE\t");
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
if (want < 0) { want = 0; };
|
if (want < 0) {
|
||||||
|
let mtt: str = "tagged typetest: type not in union (rule 7)\n";
|
||||||
|
os.write(2, mtt.ptr, mtt.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tCMPQ\t$");
|
emitline("\tCMPQ\t$");
|
||||||
emitint(want: i64);
|
emitint(want: i64);
|
||||||
emitline(", AX\n");
|
emitline(", AX\n");
|
||||||
@@ -982,7 +990,11 @@ fn cgtypeassert(c: *cgen, n: *syntax.node) void = {
|
|||||||
emitlabel(okl);
|
emitlabel(okl);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (want < 0) { want = 0; };
|
if (want < 0) {
|
||||||
|
let mtt: str = "tagged typetest: type not in union (rule 7)\n";
|
||||||
|
os.write(2, mtt.ptr, mtt.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitoff(scrutoff: i64);
|
emitoff(scrutoff: i64);
|
||||||
emitline("(BP), AX\n");
|
emitline("(BP), AX\n");
|
||||||
@@ -3115,7 +3127,12 @@ fn matcharmwant(c: *cgen, scrutt: *syntax.node, pat: *syntax.node) i32 = {
|
|||||||
r = flatvariantidxt(scrutt.type_: *syntax.tinfo, pattype, false);
|
r = flatvariantidxt(scrutt.type_: *syntax.tinfo, pattype, false);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (r >= 0) { want = r; };
|
if (r < 0) {
|
||||||
|
let mmt: str = "tagged match: case type not in union (rule 7)\n";
|
||||||
|
os.write(2, mmt.ptr, mmt.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
|
want = r;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return want;
|
return want;
|
||||||
@@ -10439,7 +10456,11 @@ fn cgassign(c: *cgen, n: *syntax.node) void = {
|
|||||||
if (viaptr) { emitline("\tMOVQ\t(BX), BX\n"); };
|
if (viaptr) { emitline("\tMOVQ\t(BX), BX\n"); };
|
||||||
emitline("\tPOPQ\tAX\n");
|
emitline("\tPOPQ\tAX\n");
|
||||||
let v58tag: i32 = taggedvariantindext(c, fi.tnode.type_: *syntax.tinfo, n.rhs);
|
let v58tag: i32 = taggedvariantindext(c, fi.tnode.type_: *syntax.tinfo, n.rhs);
|
||||||
if (v58tag < 0) { v58tag = 0; };
|
if (v58tag < 0) {
|
||||||
|
let mws: str = "tagged widen: no variant tag for source (rule 7)\n";
|
||||||
|
os.write(2, mws.ptr, mws.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tMOVQ\t$");
|
emitline("\tMOVQ\t$");
|
||||||
emitint(v58tag: i64);
|
emitint(v58tag: i64);
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
|
|||||||
@@ -1211,8 +1211,12 @@ fn cgreturn(c: *cgen, n: *syntax.node) void = {
|
|||||||
emitline("\tMOVQ\t$0, R8\n");
|
emitline("\tMOVQ\t$0, R8\n");
|
||||||
};
|
};
|
||||||
};};};
|
};};};
|
||||||
|
if (idx < 0) {
|
||||||
|
let mtag: str = "tagged return: no variant tag for return value (rule 7)\n";
|
||||||
|
os.write(2, mtag.ptr, mtag.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tMOVQ\t$");
|
emitline("\tMOVQ\t$");
|
||||||
if (idx < 0) { idx = 0; };
|
|
||||||
emitint(idx: i64);
|
emitint(idx: i64);
|
||||||
emitline(", AX\n");
|
emitline(", AX\n");
|
||||||
emitline("\tMOVQ\tBP, SP\n");
|
emitline("\tMOVQ\tBP, SP\n");
|
||||||
@@ -1847,7 +1851,11 @@ fn cgreturn(c: *cgen, n: *syntax.node) void = {
|
|||||||
if (sretretsize(c, c.fnret) > 0) {
|
if (sretretsize(c, c.fnret) > 0) {
|
||||||
let sa38: i32 = localfind(c, "@sretarg");
|
let sa38: i32 = localfind(c, "@sretarg");
|
||||||
let vidx38: i32 = voidvariantindex(c.fnret);
|
let vidx38: i32 = voidvariantindex(c.fnret);
|
||||||
if (vidx38 < 0) { vidx38 = 0; };
|
if (vidx38 < 0) {
|
||||||
|
let mvd: str = "tagged return: no void variant (rule 7)\n";
|
||||||
|
os.write(2, mvd.ptr, mvd.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitoff(sa38: i64);
|
emitoff(sa38: i64);
|
||||||
emitline("(BP), BX\n");
|
emitline("(BP), BX\n");
|
||||||
@@ -1868,7 +1876,11 @@ fn cgreturn(c: *cgen, n: *syntax.node) void = {
|
|||||||
emitline("\tMOVQ\t$0, AX\n");
|
emitline("\tMOVQ\t$0, AX\n");
|
||||||
} else {
|
} else {
|
||||||
let idx: i32 = voidvariantindex(c.fnret);
|
let idx: i32 = voidvariantindex(c.fnret);
|
||||||
if (idx < 0) { idx = 0; };
|
if (idx < 0) {
|
||||||
|
let mvd: str = "tagged return: no void variant (rule 7)\n";
|
||||||
|
os.write(2, mvd.ptr, mvd.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tMOVQ\t$");
|
emitline("\tMOVQ\t$");
|
||||||
emitint(idx: i64);
|
emitint(idx: i64);
|
||||||
emitline(", AX\n");
|
emitline(", AX\n");
|
||||||
@@ -2301,7 +2313,11 @@ fn cgletbody(c: *cgen, n: *syntax.node, off: i32) void = {
|
|||||||
nidx2 += 1;
|
nidx2 += 1;
|
||||||
};
|
};
|
||||||
}; };
|
}; };
|
||||||
if (nidx < 0) { nidx = 1; };
|
if (nidx < 0) {
|
||||||
|
let mnm: str = "tryprop: no nomem variant in fn return union (rule 7)\n";
|
||||||
|
os.write(2, mnm.ptr, mnm.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tMOVQ\t$");
|
emitline("\tMOVQ\t$");
|
||||||
emitint(nidx: i64);
|
emitint(nidx: i64);
|
||||||
emitline(", AX\n");
|
emitline(", AX\n");
|
||||||
|
|||||||
@@ -4016,7 +4016,11 @@ fn cgwidentagremap(c: *cgen, du: *syntax.tinfo, su: *syntax.tinfo, slot_off: i32
|
|||||||
let idx: i32 = 0;
|
let idx: i32 = 0;
|
||||||
for (p != nil) {
|
for (p != nil) {
|
||||||
let di: i32 = flatvariantidxt(dt, p.type_, false);
|
let di: i32 = flatvariantidxt(dt, p.type_, false);
|
||||||
if (di < 0) { di = 0; };
|
if (di < 0) {
|
||||||
|
let mrm: str = "tagged widen: source variant missing from dst union (rule 7)\n";
|
||||||
|
os.write(2, mrm.ptr, mrm.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
if (di != idx) { identity = false; p = nil; }
|
if (di != idx) { identity = false; p = nil; }
|
||||||
else { p = p.tnext; idx += 1; };
|
else { p = p.tnext; idx += 1; };
|
||||||
};
|
};
|
||||||
@@ -4030,7 +4034,11 @@ fn cgwidentagremap(c: *cgen, du: *syntax.tinfo, su: *syntax.tinfo, slot_off: i32
|
|||||||
for (p != nil) {
|
for (p != nil) {
|
||||||
let next: str = mklabel(c, "remap_next");
|
let next: str = mklabel(c, "remap_next");
|
||||||
let di: i32 = flatvariantidxt(dt, p.type_, false);
|
let di: i32 = flatvariantidxt(dt, p.type_, false);
|
||||||
if (di < 0) { di = 0; };
|
if (di < 0) {
|
||||||
|
let mrm: str = "tagged widen: source variant missing from dst union (rule 7)\n";
|
||||||
|
os.write(2, mrm.ptr, mrm.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tCMPQ\t$");
|
emitline("\tCMPQ\t$");
|
||||||
emitint(idx: i64);
|
emitint(idx: i64);
|
||||||
emitline(", AX\n");
|
emitline(", AX\n");
|
||||||
@@ -5126,7 +5134,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_of
|
|||||||
zoff += 8;
|
zoff += 8;
|
||||||
};
|
};
|
||||||
let tag: i32 = taggedvariantindext(c, dt, src);
|
let tag: i32 = taggedvariantindext(c, dt, src);
|
||||||
if (tag < 0) { tag = 0; };
|
if (tag < 0) {
|
||||||
|
let mws: str = "tagged widen: no variant tag for source (rule 7)\n";
|
||||||
|
os.write(2, mws.ptr, mws.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
if (src.kind == syntax.nkind.N_STRUCTLIT) {
|
if (src.kind == syntax.nkind.N_STRUCTLIT) {
|
||||||
// #23: delegate to the single fill path. The
|
// #23: delegate to the single fill path. The
|
||||||
// inline field loop this replaces was a
|
// inline field loop this replaces was a
|
||||||
@@ -5206,7 +5218,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_of
|
|||||||
emitoff((slot_off + 24): i64);
|
emitoff((slot_off + 24): i64);
|
||||||
emitline("(BP)\n");
|
emitline("(BP)\n");
|
||||||
let tag: i32 = taggedvariantindext(c, dt, src);
|
let tag: i32 = taggedvariantindext(c, dt, src);
|
||||||
if (tag < 0) { tag = 0; };
|
if (tag < 0) {
|
||||||
|
let mws: str = "tagged widen: no variant tag for source (rule 7)\n";
|
||||||
|
os.write(2, mws.ptr, mws.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tMOVQ\t$");
|
emitline("\tMOVQ\t$");
|
||||||
emitint(tag: i64);
|
emitint(tag: i64);
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
@@ -5309,7 +5325,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_of
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
let tag: i32 = taggedvariantindext(c, dt, src);
|
let tag: i32 = taggedvariantindext(c, dt, src);
|
||||||
if (tag < 0) { tag = 0; };
|
if (tag < 0) {
|
||||||
|
let mws: str = "tagged widen: no variant tag for source (rule 7)\n";
|
||||||
|
os.write(2, mws.ptr, mws.len: u64);
|
||||||
|
os.exit(1);
|
||||||
|
};
|
||||||
emitline("\tMOVQ\t$");
|
emitline("\tMOVQ\t$");
|
||||||
emitint(tag: i64);
|
emitint(tag: i64);
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
|
|||||||
Reference in New Issue
Block a user